算法(5)- 鏈表一【翻轉(zhuǎn)鏈表】

說在前面:

1半夷、鏈表不支持隨機的訪問元素胳挎,需從頭一次遍歷到要訪問的節(jié)點饼疙。
2、思路
(1)設(shè)立頭結(jié)點慕爬。
(2)借助輔助指針窑眯,修改節(jié)點的next指針實現(xiàn)。(穿針引線)
(3)刪除當(dāng)前節(jié)點医窿,且前一節(jié)點未知時磅甩。可將后一節(jié)點的值賦給當(dāng)前節(jié)點姥卢,再刪除后一節(jié)點卷要。
(4)不改變鏈表結(jié)構(gòu),通過修改節(jié)點值實現(xiàn)(一般不這樣)
2独榴、注意(1)與(2)的區(qū)別僧叉。

(1)ListNode cur = L1;
(2)ListNode cur = null;    cur.next = L1;

3、鏈表初始化及打印

       // 初始化head鏈表
        ListNode head = new ListNode(2);
        ListNode current = head;
        for (int j = 3; j < 10; j++) {
            current .next = new ListNode(j);
            current = current .next;
        }

      // 打印鏈表head
       ListNode resout = head;
        while (resout != null){
            System.out.println(resout.val);
            resout = resout.next;
        }
一棺榔、翻轉(zhuǎn)鏈表例題
1. 206 翻轉(zhuǎn)鏈表 Reverse Linked List

題目:反轉(zhuǎn)一個單鏈表瓶堕。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進(jìn)階:
你可以迭代或遞歸地反轉(zhuǎn)鏈表。你能否用兩種方法解決這道題症歇?

  • 一般來說捞烟,鏈表相關(guān)不能只改變節(jié)點的值,而應(yīng)該改變next指針實現(xiàn)当船。
    設(shè)立指針(引用)
題意.png
思路

(1)利用三個輔助指針题画,修改節(jié)點的next指針實現(xiàn)。

    public static ListNode reverseList(ListNode head) {
        /**
         *  利用三個輔助指針德频,修改節(jié)點的next指針實現(xiàn)苍息。
         * 執(zhí)行用時:0 ms, 在所有 Java 提交中擊敗了100.00% 的用戶
         * 內(nèi)存消耗:39.5 MB, 在所有 Java 提交中擊敗了5.06% 的用戶
         */
        ListNode pre = head;
        ListNode cur = null;
        ListNode nex = null;
        if (pre != null){
            cur = head.next;
        }
        if (cur != null){
            nex = cur.next;
        }
        head.next = null;
        while (cur != null){
            cur.next = pre;
            pre = cur;
            cur = nex;
            if (nex != null){
                nex = nex.next;
            }
        }
        // ————測試輸出節(jié)點
        ListNode resout = pre;
        while (resout != null){
            System.out.println(resout.val);
            resout = resout.next;
        }
        return resout;
}

(2) 通過修改節(jié)點的值實現(xiàn)翻轉(zhuǎn)。

 /**
         *  通過修改節(jié)點的值實現(xiàn)翻轉(zhuǎn)壹置。輔助 HashMap 記錄節(jié)點值竞思,再反向賦給節(jié)點。
         * 執(zhí)行用時:2 ms, 在所有 Java 提交中擊敗了5.09% 的用戶
         * 內(nèi)存消耗:39.3 MB, 在所有 Java 提交中擊敗了5.06% 的用戶
         */
        Map<Integer, Integer> a = new HashMap<Integer, Integer>();
        int b = 0;
        // 用map記錄節(jié)點的值
        ListNode cur = head;
        while (cur != null){
            a.put(b,cur.val);
            b++;
            cur = cur.next;
        }
        // 依次修改節(jié)點的值
        cur = head;
        while (cur !=null){
            cur.val = a.get(--b);
            cur = cur.next;
        }
        // 輸出打印節(jié)點
        cur = head;
        while (cur!=null){
            System.out.println(cur.val);
            cur = cur.next;
        }
        return head;
C++解題示例
2. 92 反轉(zhuǎn)鏈表II Reverse Linked List II ——比較復(fù)雜

題目
反轉(zhuǎn)從位置 mn 的鏈表钞护。請使用一趟掃描完成反轉(zhuǎn)盖喷。
說明:1 ≤ mn ≤ 鏈表長度。
示例:
輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL

  • 本題借助五個“指針”难咕,注意越界問題课梳,及循環(huán)條件距辆。
  • 注意特殊情況,如m=n暮刃,n=最后一個節(jié)點等等跨算。
思路
 public static ListNode reverseBetween(ListNode head, int m, int n) {
        /**
         * 反轉(zhuǎn)從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉(zhuǎn)椭懊。
         * 1 ≤ m ≤ n ≤ 鏈表長度诸蚕。
         * 執(zhí)行用時:0 ms, 在所有 Java 提交中擊敗了100.00% 的用戶
         * 內(nèi)存消耗:37.4 MB, 在所有 Java 提交中擊敗了8.70% 的用戶
         */
        if (m==n){
            return head;
        }
        ListNode pre = null;
        ListNode first = null;
        ListNode cur = head;   // 當(dāng)前節(jié)點,與下面a相等
        ListNode nex = null;   // 下一節(jié)點氧猬,
        ListNode last = null;  // 下下節(jié)點背犯,用于找到nex
        if (cur.next != null){
            nex = cur.next;
        }
        int a = 1;   
        // 當(dāng)a屬于[m,n]中,并且nex不為空盅抚,或者a = n(即n是最后一個節(jié)點時)
        while ((nex != null && a<n+1) || a==n){
            if (a==m-1){
                pre = cur;
                first = nex;
            }
            if (a<m){
                cur = nex;
                if (nex.next != null){
                    nex = nex.next;
                }
            }
            if (m==1){
                first = head;
                pre = head;
            }
            if (a>=m && a<n){
                // a>=m a<n 時媳板,cur指針后移,nex指針后移泉哈,a++蛉幸,nex指針
                last = nex.next;
                nex.next = cur;
                cur = nex;
                nex = last;
            }
            if (a == n){
                pre.next = cur;
                first.next = nex;
                if (m==1){
                    head = cur;
                }
            }
            a++;
        }
        return head;
    }
3. 328 奇偶鏈表

題目:給定一個單鏈表,把所有的奇數(shù)節(jié)點和偶數(shù)節(jié)點分別排在一起丛晦。請注意奕纫,這里的奇數(shù)節(jié)點和偶數(shù)節(jié)點指的是節(jié)點編號的奇偶性,而不是節(jié)點的值的奇偶性烫沙。
請嘗試使用原地算法完成匹层。你的算法的空間復(fù)雜度應(yīng)為 O(1),時間復(fù)雜度應(yīng)為 O(nodes)锌蓄,nodes 為節(jié)點總數(shù)升筏。
示例 1:
輸入: 1->2->3->4->5->NULL
輸出: 1->3->5->2->4->NULL

算法思路:設(shè)置三個輔助指針,先找到奇數(shù)偶數(shù)節(jié)點的next指針瘸爽,再將奇節(jié)點的最后一個指針指向偶數(shù)節(jié)點的第一個指針您访。

class Solution {
    public ListNode oddEvenList(ListNode head) {
        ListNode nowNode = head;
        ListNode secNode = null;
        ListNode nowSecNode = null;
        if(head == null){
            return head;
        }
        if(head.next != null){
            System.out.println("000000");
            secNode = head.next;    // 第二個節(jié)點
            nowSecNode = head.next; 
        }else{
            return head;
        }
// 先不管奇數(shù)最后一個指針,先排好兩個鏈表剪决。然后再連起來
        while(nowNode.next != null && nowNode.next.next != null){
            nowSecNode = nowNode.next;
            nowNode.next = nowSecNode.next;
            nowNode = nowSecNode.next;
            nowSecNode.next = nowNode.next;
        }
        nowNode.next = secNode;
        return head;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灵汪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柑潦,更是在濱河造成了極大的恐慌享言,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渗鬼,死亡現(xiàn)場離奇詭異览露,居然都是意外死亡,警方通過查閱死者的電腦和手機譬胎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門差牛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來命锄,“玉大人,你說我怎么就攤上這事多糠±巯希” “怎么了浩考?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵夹孔,是天一觀的道長。 經(jīng)常有香客問我析孽,道長搭伤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任袜瞬,我火速辦了婚禮怜俐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邓尤。我一直安慰自己拍鲤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布汞扎。 她就那樣靜靜地躺著季稳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澈魄。 梳的紋絲不亂的頭發(fā)上景鼠,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音痹扇,去河邊找鬼铛漓。 笑死,一個胖子當(dāng)著我的面吹牛鲫构,可吹牛的內(nèi)容都是我干的浓恶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼结笨,長吁一口氣:“原來是場噩夢啊……” “哼问顷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起禀梳,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤杜窄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后算途,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塞耕,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年嘴瓤,在試婚紗的時候發(fā)現(xiàn)自己被綠了扫外。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莉钙。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筛谚,靈堂內(nèi)的尸體忽然破棺而出磁玉,到底是詐尸還是另有隱情,我是刑警寧澤驾讲,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布蚊伞,位于F島的核電站,受9級特大地震影響吮铭,放射性物質(zhì)發(fā)生泄漏时迫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一谓晌、第九天 我趴在偏房一處隱蔽的房頂上張望掠拳。 院中可真熱鬧,春花似錦纸肉、人聲如沸溺欧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐刁。三九已至,卻和暖如春预吆,著一層夾襖步出監(jiān)牢的瞬間龙填,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工拐叉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留岩遗,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓凤瘦,卻偏偏與公主長得像宿礁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蔬芥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348