【备战字节面试】算法特训-链表

235 阅读2分钟

简单粗暴,记录备战过程,持续更新

链表

链表数据结构都太熟了,不多说了。

适用场景

链表场景

实战

实战1,leetcode 234. 回文链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        // 1, slow是中间节点
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast != null && fast.next !=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        // 2,截取一半反转
        slow.next = reversalList(slow.next);

        // 3,比较节点
        boolean bool = true;
        ListNode diffLeft = head;
        ListNode diffRight = slow.next;
        while(diffRight != null){
            if(diffLeft.val != diffRight.val){
                bool = false;
                break;
            }
            diffLeft = diffLeft.next;
            diffRight = diffRight.next;
        }
        // 4,链表恢复
        slow.next = reversalList(slow.next);

        return bool;
    }
    
    // 反转链表
    private ListNode reversalList(ListNode head){
        ListNode pre = null;
        ListNode curr = head;
        while(curr != null){
            ListNode tmp = curr.next;
            curr.next = pre;
            pre = curr;
            curr = tmp;
        }
        return pre;
    }
}

实战2,leetcode 206. 反转链表

public ListNode reverseList(ListNode head) {
        // 1,判空
        if(head == null){
            return head;
        }
        // 2,反转
        ListNode pre = null;
        ListNode curr = head;
        while(curr != null){
            ListNode tmp = curr.next;
            curr.next = pre;
            pre = curr;
            curr = tmp;
        }
        return pre;
    }

实战3,leetcode 25. K 个一组翻转链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode pre = head;
        ListNode curr  = new ListNode();
        curr.next = head;

        ListNode ret = curr;
        while(pre != null){
            int step = k;
            // 1, 到下一组头
            while(pre != null && step > 0){
                pre = pre.next;
                step--;
            }
            // 2,step 剩余0,反转链表
            if(step == 0){
                curr.next = reversalList(curr.next , pre);
                while(curr.next != pre ){
                    curr = curr.next;
                }
            }
        }
        return ret.next;
    }

   // 反转
    private ListNode reversalList(ListNode head , ListNode tail){
        ListNode pre = tail;
        ListNode curr = head;
        while(curr != tail){
                ListNode temp = curr.next;
                curr.next = pre;
                pre = curr;
                curr = temp;
        }
        return pre;
    }
}

实战4,leetcode 141. 环形链表

public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null){
            return false;
        }
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast != slow){
            if (fast == null || fast.next == null){
                return false;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        return true;
    }

实战4,leetcode 148. 排序链表

实战5,leetcode 160. 相交链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null){
            return null;
        }
        int aLen = getLength(headA);
        int bLen = getLength(headB);
        int step = aLen >= bLen ? aLen - bLen : bLen - aLen;
        if(aLen >= bLen){
            while(step > 0 ){
                headA = headA.next;
                step--;
            }
        }else{
            while(step > 0 ){
                headB = headB.next;
                step--;
            }
        }

        while(headA != null && headB != null){
            if(headA == headB){
                return headA;
            }
            headA = headA.next;
            headB = headB.next;
        }
        return null;
    }

    private int getLength(ListNode head){
        int ret = 0 ;
        while(head != null){
            head = head.next;
            ret++;
        }
        return ret;
    }
}

实战6, 82. 删除排序链表中的重复元素 II

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null){
            return head;
        }
        ListNode tmpHead = new ListNode(0,head);
        ListNode slow = tmpHead;
        ListNode fast = head;
        while(fast != null ){
            while(fast != null && fast.next != null && fast.val == fast.next.val){
                int tmp = fast.val;
                while(fast != null && fast.val == tmp){
                    fast = fast.next;
                }
            }
            slow.next = fast;
            slow = slow.next;
            if(fast != null){
                fast = fast.next;
            }
        }
        return tmpHead.next;
    }
}