Leetcode鏈表題目集合

160.Intersection of Two Linked Lists

注意,鏈表結點相同意味着他們的值相同,下一個結點也相同

方法1:暴力法
方法2:

/**
 * 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;
            ListNode pa=headA,pb=headB;
            while(pa!=pb)
            {
                pa=pa==null?headA:pa.next;
                pb=pb==null?headB:pb.next;
            }
            
            return pa;
    }
}

方法3哈希法:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        HashSet<ListNode> set=new HashSet();
        while (headA!=null){
            set.add(headA);
            headA=headA.next;
        }
        while (headB!=null){
            if(set.contains(headB))
                return headB;
            headB=headB.next;
        }
        return null;
    }
}

206 Reverse Linked List

頭插法:

class Solution {
 public ListNode reverseList(ListNode head) {
    ListNode newHead = null;
  
    while (head != null) {
        ListNode next = head.next;
        head.next = newHead;//畫圖理解
        newHead = head;
        head = next;
    }
    return newHead;
}

}

遞歸解法:

public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode next = head.next;
ListNode newHead = reverseList(next);
next.next = head;
head.next = null;
return newHead;
}

21. 合併兩個有序鏈表

遞歸解法:

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

83. 刪除排序鏈表中的重複元素

遞歸解法:

 class Solution {
    public ListNode deleteDuplicates(ListNode head) {
         if(head==null||head.next==null)
            return head;
        head.next=deleteDuplicates(head.next);
        return head.val==head.next.val?head.next:head;
    }
}

19. 刪除鏈表的倒數第N個節點

①解法1:兩次遍歷,統計鏈表的長度
②快慢指針

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode first = dummy;
    ListNode second = dummy;
    // Advances first pointer so that the gap between first and second is n nodes apart
    for (int i = 1; i <= n + 1; i++) {
        first = first.next;
    }
    // Move first to the end, maintaining the gap
    while (first != null) {
        first = first.next;
        second = second.next;
    }
    second.next = second.next.next;
    return dummy.next;
}

24. 兩兩交換鏈表中的節點

①解法一 遞歸:

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null||head.next==null) 
        /*先判斷head在判斷next*/
            return head;
        ListNode next= head.next;
        head.next=swapPairs(head.next.next);
        next.next=head;
        return next;
    }
}

②解法二迭代:

public ListNode swapPairs(ListNode head) {
    ListNode node = new ListNode(-1);
    node.next = head;
    ListNode pre = node;
while (pre.next != null && pre.next.next != null) {
    ListNode l1 = pre.next, l2 = pre.next.next;
    ListNode next = l2.next;
    l1.next = next;
    l2.next = l1;
    pre.next = l2;
    pre = l1;
}
    return node.next;
}

445. 兩數相加 II

逆序處理:用棧,carray表示進位

class Solution {
   public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    Stack<Integer> l1Stack = buildStack(l1);
    Stack<Integer> l2Stack = buildStack(l2);
    ListNode head = new ListNode(-1);
    int carry = 0;
    while (!l1Stack.isEmpty() || !l2Stack.isEmpty() || carry != 0) {
        int x = l1Stack.isEmpty() ? 0 : l1Stack.pop();
        int y = l2Stack.isEmpty() ? 0 : l2Stack.pop();
        int sum = x + y + carry;
        ListNode node = new ListNode(sum % 10);
        node.next = head.next;
        head.next = node;
        carry = sum / 10;
    }
    return head.next;
}
private Stack<Integer> buildStack(ListNode l) {
    Stack<Integer> stack = new Stack<>();
    while (l != null) {
        stack.push(l.val);
        l = l.next;
    }
    return stack;
}
}

2. 兩數相加

這裏直接遍歷就可,做法也是一樣,t表示進位

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummyHead = new ListNode(-1), pre = dummyHead;
        int t = 0;
        while (l1 != null || l2 != null || t != 0) {
            if (l1 != null) {
                t += l1.val;
                l1 = l1.next;
            }
            if (l2 != null) {
                t += l2.val;
                l2 = l2.next;
            }
            pre.next = new ListNode(t % 10);
            pre = pre.next;
            t /= 10;
        }

        return dummyHead.next;
    }
}

234. 迴文鏈表

快慢指針,逆轉鏈表

class Solution {
public:
    //題解:快慢指針法,快指針走兩步,慢指針走一步,找到鏈表的中點。然後,翻轉後半部分。最後從頭、中點開始判斷是否相同。
    bool isPalindrome(ListNode* head) {
        if(!head||!head->next)return true;
        ListNode *fast=head,*slow=head,*pre=nullptr;
        //1、找到鏈表的中點,鏈表長度奇偶不影響
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        //2、將slow之後鏈表進行斷開且反轉,最後翻轉完成之後pre指向反轉鏈表的頭節點
        while(slow){
            ListNode *p=slow->next;
            slow->next=pre;
            pre=slow;
            slow=p;
        }
        //3、前後鏈表進行比較,注意若爲奇數鏈表,後半部分回比前部分多1一個節點,然而我們只比較相同長度的節點值,巧妙地避開這點判斷
        while(head&&pre){
            if(head->val!=pre->val)return false;
            head=head->next;
            pre=pre->next;
        }
        return true;
    }
};

725. 分隔鏈表

注意一個地方:
ListNode temm=temp; 比如這裏,temm和temp屬於同一個結點,如果把temm的next設置爲空,那麼temp的next也爲空
題目描述:把鏈表分隔成 k 部分,每部分的長度都應該儘可能相同,排在前面的長度應該大於等於後面的。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode[] splitListToParts(ListNode root, int k) {
         ListNode p=root;
         ListNode[] listArrary=new ListNode[k];
         int listLength=0,avgLength=0,leftLength=0;
         while(p!=null){
             p=p.next;
             listLength++;
         }
         avgLength=listLength/k;            //*每一個數組元素的長度*/
         leftLength=listLength%k;               //*剩餘的長度 */
         if(listLength<=k){
            ListNode temp=root;
            for(int i=0;i<k;i++){
                if(temp!=null){
                    listArrary[i]=temp;           //  注意 listArrary[i]=temp;   那麼這兩個就是同一個結點
                    ListNode temm=temp.next;    //這裏一定要暫存temp.next的結點;
                    listArrary[i].next=null;
                    temp=temm;
                }
                else
                listArrary[i]=null;
                 
            }
             return listArrary;
         }
         for(int i=0;i<k;i++){
             listArrary[i]=root;
             for(int j=0;j<avgLength-1;j++){
                    root=root.next;
             }
             ListNode temp=null;
             if(leftLength!=0){             //看看是否還有剩餘長度
                root=root.next;
                temp=root.next;
                root.next=null;
                leftLength--;
             }
             else       
             {
                 temp=root.next;
                 root.next=null;
             }
            root=temp;
         }
         return listArrary;
    }
}

328. 奇偶鏈表

畫圖快速理解

class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head==null) 
        return head;
        ListNode first=head,two=head.next,third=two; 
         //分別指向奇結點和偶節點,third用來連接成功後的奇偶鏈表

        while(two!=null&&two.next!=null){  
            //two不爲空,first必不爲空,first爲不空,two可能爲空           
            //two指針一定在first後面,所以判斷two就可以了         
            first.next=first.next.next;
            first=first.next;
            two.next=two.next.next;
            two=two.next;
        }
        first.next=third;
        return head;                            //返回頭指針
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章