LeetCode鏈表問題匯總!

一、LeetCode-160、相交鏈表
  • 解題思路:對于兩條相交鏈表來說,長鏈表減去短鏈表即為他們兩個的差值,可以讓短的走完從新指向長的鏈表的頭部,當(dāng)長的走完的時候,兩條鏈表正好處于平行的狀態(tài),當(dāng)節(jié)點相等的時候即使交點。
 public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null){
            return null;
        }
        ListNode A=headA;
        ListNode B=headB;
        while(A!=B){
            if(A==null){
                A=headB;
            }else{
                A=A.next;
            }
            if(B==null){
                B=headA;
            }else{
                B=B.next;
            }
        }
        return A;
    }
二、LeetCode-206、反轉(zhuǎn)鏈表

1、雙指針迭代

  • 解題思路:我們可以申請兩個指針,第一個指針叫 pre,最初是指向 null 的。第二個指針 cur 指向 head,然后不斷遍歷 cur。每次迭代到 cur,都將 cur 的 next 指向 pre,然后 pre 和 cur 前進一位。都迭代完了(cur 變成 null 了),pre 就是最后一個節(jié)點了。
public ListNode reverseList(ListNode head) {
        //申請節(jié)點,pre和 cur,pre指向null
        ListNode pre = null;
        ListNode cur = head;
        ListNode tmp = null;
        while(cur!=null) {
            //記錄當(dāng)前節(jié)點的下一個節(jié)點
            tmp = cur.next;
            //然后將當(dāng)前節(jié)點指向pre
            cur.next = pre;
            //pre和cur節(jié)點都前進一位
            pre = cur;
            cur = tmp;
        }
        return pre;
    }

2、遞歸解法(騷操作!?。?/strong>

  • 解題思路:遞歸的兩個條件:
  1. 終止條件是當(dāng)前節(jié)點或者下一個節(jié)點==null
  2. 在函數(shù)內(nèi)部,改變節(jié)點的指向,也就是 head 的下一個節(jié)點指向 head 遞歸函數(shù)那句 head.next.next = head
public ListNode reverseList(ListNode head) {
        //遞歸終止條件是當(dāng)前為空,或者下一個節(jié)點為空
        if(head==null || head.next==null) {
            return head;
        }
        //這里的cur就是最后一個節(jié)點
        ListNode cur = reverseList(head.next);
        //這里請配合動畫演示理解
        //如果鏈表是 1->2->3->4->5,那么此時的cur就是5
        //而head是4,head的下一個是5,下下一個是空
        //所以head.next.next 就是5->4
        head.next.next = head;
        //防止鏈表循環(huán),需要將head.next設(shè)置為空
        head.next = null;
        //每層遞歸函數(shù)都返回cur,也就是最后一個節(jié)點
        return cur;
    }
三、LeetCode-21、合并兩個有序鏈表

1、遞歸方法解題

  • 解題思路:取出來一個數(shù)之后,剩下的仍然是這道題的一個問題,因此可以使用遞歸。
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        else if (l2 == null) {
            return l1;
        }
        else if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }
        else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }

2、迭代方法解題

  • 解題思路:首先,我們設(shè)定一個哨兵節(jié)點 "prehead" ,這可以在最后讓我們比較容易地返回合并后的鏈表。我們維護一個 prev 指針,我們需要做的是調(diào)整它的 next 指針。然后,我們重復(fù)以下過程,直到 l1 或者 l2 指向了 null :如果 l1 當(dāng)前位置的值小于等于 l2 ,我們就把 l1 的值接在 prev 節(jié)點的后面同時將 l1 指針往后移一個。否則,我們對 l2 做同樣的操作。不管我們將哪一個元素接在了后面,我們都把 prev 向后移一個元素。
  • 在循環(huán)終止的時候, l1 和 l2 至多有一個是非空的。由于輸入的兩個鏈表都是有序的,所以不管哪個鏈表是非空的,它包含的所有元素都比前面已經(jīng)合并鏈表中的所有元素都要大。這意味著我們只需要簡單地將非空鏈表接在合并鏈表的后面,并返回合并鏈表。
  • 問題:這個和一開始我自己想的是一樣的,但是這段代碼沒有考慮存在空鏈表的情況,只考慮了都存在的情況
  • 另外對于怎樣存儲頭節(jié)點:這里的方法很好,可以先建一個已知數(shù)據(jù)的一個節(jié)點,最終返回該節(jié)點的next即使頭節(jié)點
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // maintain an unchanging reference to node ahead of the return node.
        ListNode prehead = new ListNode(-1);

        ListNode prev = prehead;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                prev.next = l1;
                l1 = l1.next;
            } else {
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }

        // exactly one of l1 and l2 can be non-null at this point, so connect
        // the non-null list to the end of the merged list.
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
四、LeetCode-26、刪除排序數(shù)組中的重復(fù)項

1、雙指針迭代

  • 解題思路:我們可以申請兩個指針,第一個指針叫i,最初是指向0的。第二個指針 j 指向 1,然后不斷遍歷數(shù)組。每次判斷如果相等,那么i就不動,一直增長j,j肯定是比ida,遇到不等的時候?qū)的值賦值給i,最終返回i+1。
public int removeDuplicates(int[] nums) {
       int i=0;
       for(int j=1;j<nums.length;j++){
           if(nums[i]!=nums[j]){
               i++;
               nums[i]=nums[j];
           }
       }
       return i+1;
    }

2、System.arraycopy()方法的使用

  • 解題思路:在循環(huán)體中控制循環(huán)條件,因為移動了數(shù)組后面的值,因此i要減1,重新怕段i和 后一個值得關(guān)系,不然會錯過一個數(shù)。
    public int removeDuplicates(int[] nums) {
       int len=nums.length;
       for(int i=0;i<len-1;i++){
           if(nums[i]==nums[i+1]){
               System.arraycopy(nums,i+1,nums,i,len-i-1);
               len--;
               i--;
           }
       }
       return len;
    }

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容