鏈表

1、鏈表相加

題目

給定兩個鏈表,分別表示兩個非負(fù)整數(shù),逆序存儲在鏈表中,計算兩個數(shù)的和,并返回鏈表頭指針,如:
輸入:2->4->3、5->6->4,輸出7->0->8

思路及代碼

  • 常規(guī)思路:考慮到鏈表可能是不等長的,所以先將鏈表反轉(zhuǎn),這樣就可以對應(yīng)位置直接相加,注意考慮進位,代碼:
public class solution{
    public ListNode addTwoNumber(ListNode l1, ListNode l2){
        l1 = reverseList(l1);
        l2 = reverseList(l2);
        ListNode sumReverseList = addTwoNumbersReversed(l1, l2);
        reverseList(l1);
        reverseList(l2);
        return reverseList(sumReversed);
    }
    
    public ListNode addTwoNumbersReversed(ListNode l1, ListNode l2){
        ListNode head = new ListNode(0);
        ListNode curr = head;
        int carry = 0;
        while(l1 != null || l2 != null || carry == 1){
            int sum = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + carry;
            if(sum > 9){
                carry = 1;
                sum /= 10;
            }
            else{
                carry = 0;
            }
            curr.next = new ListNode(sum);
            curr = curr.next;
            if(l1 != null){
                l1 = l1.next;
            }
            if(l2 != null){
                l2 = l2.next;
            }
        }
        return head.next;
    }

    public ListNode reverseList(ListNode head){
        ListNode curr = head;
        ListNode next;
        ListNode prev = null;
        while(curr != null){
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}
  • 遞歸版本:
public class solution{
    public ListNode addTwoNumbers(ListNode l1, ListNode l2){
        if(l1 == null || l2 == null){
            return l1 == null ? l2 : l1;
        }
        return addTwoNumbers_3(l1, l2, 0);
    }

    public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carry){
        if(l1 == null && l2 == null){
            return carry == 0 ? null : new ListNode(1);
        }
        int num1 = l1 == null ? 0 : l1.val;
        int num2 = l2 == null ? 0 : l2.val;
        boolean flag = false;
        int sum = num1 + num2 + carry;
        if(sum > 9){
            flag = true;
            sum = sum - 10;
        }
        ListNode res = new ListNode(sum);
        res.next = addTwoNumbers_3(l1 == null ? l1 : l1.next, l2 == null ? l2 : l2.next, flag ? 1 : 0);
        return res;
    }
}
  • 堆棧版本:首先將list都放入stack中,再進行操作
public class solution{
    public ListNode addTwoNumbers_1(ListNode l1, ListNode l2){
        Stack<Integer> s1 = new Stack<Integer>();
        Stack<Integer> s2 = new Stack<Integer>();

        while(s1 != null){
            s1.push(l1.val);
            l1 = l1.next;
        }
        while(s2 != null){
            s2.push(l2.val);
            l2 = l2.next;
        }

        int sum = 0;
        ListNode list = new ListNode(0);
        while(!s1.empty() || !s2.empty()){
            if(!s1.empty()){
                sum += s1.pop();
            }
            if(!s2.empty()){
                sum += s2.pop();
            }
            list.val = sum % 10;
            ListNode head = new ListNode(sum / 10);
            // 此處是關(guān)鍵, 將head賦值給list,即list是不斷的增加頭部節(jié)點
            // 每次產(chǎn)生的head作為頭部添加到list中
            head.next = list;
            list = head;
            sum /= 10;
        }
        return list.val == 0 ? list.next : list;
    }
}

2、鏈表反轉(zhuǎn)

題目

給定一個鏈表,反轉(zhuǎn)該鏈表從m位置到n位置,要求直接反轉(zhuǎn)不申請額外空間
如給定1 - >2 - >3 - >4 - >5,m=2,n =4,返回1 - >4 - >3 - >2 - >5

思路及代碼

  • 全部翻轉(zhuǎn),使用遞歸
public ListNode reverseList(ListNode node){
    if(node == null || node.next == null){
        return node;
    }
    ListNode preNode = reverseList(node.next);
    node.next.next = node; #反轉(zhuǎn)
    node.next = null;
    return preNode;
}
  • 全部翻轉(zhuǎn),使用循環(huán)
public listNode reverseList(ListNode node){
    if(node == null){
        return null;
    }
    ListNode pre = null;
    ListNode next = null;
    while(node!=null){
        # 避免斷裂,先將后邊的數(shù)據(jù)存入next
        next = node.next;
        # 將當(dāng)前節(jié)點指向前節(jié)點
        node.next = pre;
        # 將當(dāng)前節(jié)點和前一節(jié)點向后移一位
        pre = node;
        node = next;
    }
    return pre;
}
  • 部分翻轉(zhuǎn)


    reverseList示意圖
public class solution{
    public ListNode reverseList(ListNode head, int from, int to){
        ListNode preHead = new ListNode(0);
        preHead.next = head;
        // 定義curr節(jié)點,從prehead開始,找到第m-1個節(jié)點,作為curPre
        ListNode curr = preHead;
        for(int i = 1; i < from; i++){
            curr = curr.next;
        }
        ListNode curPre = curr;
        curr = curr.next;
        ListNode curNext = null;
        for(int i=from; i<to; i++){
            curNext = curr.next;
            curr.next = curNext.next;
            curNext.next = curPre.next;
            curPre.next = curNext;
        }
        return preHead.next;
    }
}

鏈表去重,待補充...

題目

給定排序的鏈表,刪除重復(fù)的節(jié)點,只保留重復(fù)元素第一次出現(xiàn)的節(jié)點,如:
給定:2->3->3->5->7->8->8->8->9->9->10
返回:2->3->5->7->8->9->10

思路及代碼

若p.next的值與p相等,則將p.next.next指向p,刪除p.next,重復(fù)此過程,至鏈表尾端

鏈表劃分

題目

給定一個鏈表和一個值x,將鏈表劃分成兩部分,使得劃分后小于x的節(jié)點在前,大于x的節(jié)點在后,且保持原鏈表中出現(xiàn)的順序不變,如:
給定1->4->3->2->5->2和x=3,返回1->2->2->4->3->5

思路及代碼

鏈表公共節(jié)點

題目

給定兩個單向鏈表,計算兩個鏈表的第一個公共節(jié)點,若沒有返回空

思路及代碼

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 搞懂單鏈表常見面試題 Hello 繼上次的 搞懂基本排序算法,這個一星期,我總結(jié)了,我所學(xué)習(xí)和思考的單鏈表基礎(chǔ)知識...
    醒著的碼者閱讀 4,734評論 1 45
  • 知識點總結(jié) 1、鏈表問題只要涉及到頭結(jié)點的操作的,一般都會用到設(shè)置虛擬頭結(jié)點這個技巧; 2、鏈表中的問題,很多可以...
    李威威閱讀 803評論 0 0
  • 考察鏈表的題目不會要求我們時間復(fù)雜度,因為鏈表并不像是數(shù)組那樣,可以方便的使用各種排序算法和查找算法。因為鏈表涉及...
    熊大狀閱讀 716評論 0 1
  • 1. 兩數(shù)相加 題目描述 Leetcode:給定兩個非空鏈表來表示兩個非負(fù)整數(shù)。位數(shù)按照逆序方式存儲,它們的每個節(jié)...
    綠葉悠閱讀 812評論 0 1
  • (一)LeetCode206.反轉(zhuǎn)鏈表 題目描述: 反轉(zhuǎn)一個單鏈表。 代碼實現(xiàn) (二)LeetCode160. 相...
    Jarily閱讀 1,483評論 0 5

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