1. 程式人生 > >給定單鏈表L:L0→L1→...→Ln-1→Ln, 重新排序:L0→Ln→L1→Ln-1→L2→Ln-2→...

給定單鏈表L:L0→L1→...→Ln-1→Ln, 重新排序:L0→Ln→L1→Ln-1→L2→Ln-2→...

本題源自leetcode  143

----------------------------------------------------------------------------

思路1:用快慢指標找到中節點,然後反轉後半部分連結串列。然後倆個連結串列交叉插入

程式碼:

void reorderList(ListNode* head) {
        if (!head || !head->next) 
            return;
    
        // find the middle node: O(n)
        ListNode *slow = head, *fast = head;
        while (fast && fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }

        // cut from the middle and reverse the second half: O(n)
        ListNode *head2 = slow->next;
        slow->next = NULL;

        ListNode *q = head2->next;
        head2->next = NULL;
        while (q) {
            ListNode *qNext = q->next;
            q->next = head2;
            head2 = q;
            q = qNext;
        }
        ListNode* p = head;
        // merge two lists: O(n)
        for (q = head2; p; ) {
            auto t = p->next;
            p->next = q;
            p = p->next;
            q = t;
        }
        /*
        slow->next = reverse(slow->next);
        ListNode* q = slow->next; 
        //reverse(slow->next);
        while(p != slow && q ){
            ListNode * qNext = q->next;
            q->next = p->next;
            p->next = q;
            p = q->next;
            q = qNext;
        }
        */
    }

程式碼2:

 void reorderList(ListNode* head) {
        if (!head || !head->next) 
            return;
    
        // find the middle node: O(n)
        ListNode *slow = head, *fast = head;
        while (fast && fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }

        // cut from the middle and reverse the second half: O(n)
        ListNode *head2 = reverse(slow->next);
        slow->next = NULL;
        ListNode* p = head, *q = head2;
        /*
        // merge two lists: O(n)
        for (; p; ) {
            auto t = p->next;
            p->next = q;
            p = p->next;
            q = t;
        }
        */
        //reverse(slow->next);
        while(p  && q ){
            ListNode * qNext = q->next;
            q->next = p->next;
            p->next = q;
            p = q->next;
            q = qNext;
        }
    }
    
    ListNode* reverse(ListNode* root){
        if(!root)
            return NULL;
        ListNode* pre = NULL;
        ListNode* p = root;
        ListNode* pNext = NULL;
        while(p){
            pNext = p->next;
            p->next = pre;
            pre = p;
            p = pNext;
        }
        return pre;
    }


相關推薦

給定單鏈LL0L1→...→Ln-1Ln 重新排序L0LnL1Ln-1L2Ln-2→...

本題源自leetcode  143 ---------------------------------------------------------------------------- 思路1:用快慢指標找到中節點,然後反轉後半部分連結串列。然後倆個連結串列交叉插入 程

設計一個遞迴演算法刪除不帶頭節點單鏈L中所有值為x的節點

#include "stdafx.h" #include<stdio.h> #include<malloc.h> #include<stdlib.h> typed

C語言單鏈實現(二) 就地逆置就地歸併

#include<iostream> #include<stdio.h> #include<math.h> #define LEN sizeof(struct Nodelist) using namespace std; typedef

給定單鏈檢測是否有環。如果有環則求出進入環的第一個節點

判斷單向連結串列是否有環,可以採用快指標與慢指標的方式來解決。即定義一個快指標fast和一個慢指標slow,使得fast每次跳躍兩個節點,slow每次跳躍一個節點。如果連結串列沒有環的話,則slow與fast永遠不會相遇(這裡連結串列至少有兩個節點);如果有環,則fast與slow將會在環中相遇。判斷出

6-6 求單鏈結點的階乘和(15 分) 本題要求實現一個函式單鏈L結點的階乘和。這裡預設所有結點的值非負且題目保證結果在int範圍內。

int FactorialSum( List L ){  int max=0,sum=0;  List p,head;  head=L;  p=head;  while(p!=NULL)  {    if(max<p->Data)    max=p->Dat

C 將一個單鏈拆成3個迴圈連結串列其中一個是純數字一個純字母一個其他字元

前面相關操作在這呢,這個函式依託於此 //結構體 typedef struct Node { ElementType data; struct Node * next; } LNode, * LinkNode; //將一個單鏈表拆成3個迴圈連結串列,其中一個是純數字

判斷單鏈是否帶環?若帶環求環的長度?求環的入口點?

判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點? 這道題有三問,是否帶環?環的長度?環的入口點? 1.單鏈表是否帶環? 思路分析:怎麼樣才算帶環呢?我們細想,如果一個單鏈錶帶環的話,那麼它怎麼走都走不出來的,而如果不帶環的話,那麼一定會走到NULL的。

判斷單鏈是否帶環?若帶環求環的長度,求環的入口點

判斷是否帶環,若帶環返回相遇點,否則返回空 pNode IsCircle(pList plist) { pNode pFast = plist; pNode pSlow = plist; while (pFast && pFast->next)

java實現---判斷單鏈是否帶環?若帶環求環的長度?求環的入口點?

判斷 單鏈表是否帶環 若帶環,求環的長度 求環的入口點 單鏈表是否帶環 判斷一個連結串列是否帶環 我們可以定義兩個快慢節點,快的一次走兩步,

單鏈應用舉例(單鏈A和單鏈B的元素都是非遞減排列利用單鏈的基本運算將它們合併成一個單鏈C要求C也是非遞減序列)

標頭檔案:函式的定義 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> typedef int ElemType; t

單鏈進行求平均數(去掉最大數最小數)

package DataStructureTestmain; import DataStructureTestSinglyLinkedList.Node; import DataStructure

用shell寫一個簡易計算器可以實現加、減、乘、除運算假如腳本名字為1.sh執行示例./1.

a-z 依次 腳本 als 示例 內置 數位 特殊字符 使用 用shell寫一個簡易計算器,可以實現加、減、乘、除運算,假如腳本名字為1.sh,執行示例:./1.sh 1 + 2#!/bin/bash if [ $# -ne 3 ] then echo "參

java基礎增強統計網上app下載情況排序

技術 rri map對象 cat -s height hang city ole 一入編程深似海,從此妹子是路人。 案例:   統計網站app下載的情況,後臺數據如下:     日期,用戶名,app名,下載渠道,所在城市,app版本     2017-08-15,xx老師,

財路網每日原創推送市值蒸發萬億之後重新認識比特幣

1 一年之內,比特幣兩度成為全民話題。一次因為暴漲,一次因為暴跌。 去年12月,比特幣價格暴漲到1.9萬美元,是當年年初1000美元價格的19倍。當時,彷彿全世界都在談論比特幣,有人後悔自己買少了,有人心疼自己賣早了,還有人遺憾金鑰弄丟了。所有人都以為牛市來了,各路牛鬼蛇神一擁而上

《資料演算法Hadoop_Spark大資料處理技巧》艾提拉筆記.docx 第1章二次排序簡介 19 第2章二次排序詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5

《資料演算法:Hadoop_Spark大資料處理技巧》艾提拉筆記.docx       第1章二次排序:簡介 19 第2章二次排序:詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5章反轉排序 127 第6章

對於大型的DataPump匯出(EXPDP)失敗錯誤ORA-1555(文件 ID 1086414.1)

症狀在某個表上執行expdp通常需要一個小時。 但是,它現在運行了一天。 問題似乎與一個表(資料庫中最大的)有關。 當DataPump匯出(expdp)啟動時,它處理的第一個表的估計處理時間超過24小時。Processing object type SCHEMA_EXPORT

vs2015正式版建立安卓工程報錯值不能為空引數名path1的錯誤解決

vs2015正式版今天已釋出,好多人都像我一樣,迫不及待的嚐鮮了吧。可是這樣的結果就是網上資料少,出了什麼問題都要自己解決。 然後這就是第一個問題,當建立安卓工程的時候回提示: “值不能為空,引數名

java練習定義一個汽車類Vehicle要求如下(知識點類的繼承 方法的覆蓋) (a)屬性包括汽車品牌brand(String型別)、顏色color(String型別)和速度speed

定義一個汽車類Vehicle,要求如下:(知識點:類的繼承 方法的覆蓋) (a)屬性包括:汽車品牌brand(String型別)、顏色color(String型別)和速度speed(double型別)。 (b)至少提供一個有參的構造方法(要求品牌和顏色可以初始化為任意

單鏈(L1L2→...→Ln) 重排為(L1LnL2Ln-1→L3→Ln-2...)

#include <stdio.h> #include <stdlib.h> typedef struct LNode{ int data ; struct LNode *next ; }LNode , *LinkList; LinkList Create

D. Powerful array 離線+莫隊算法 給定n個數m次查詢;每次查詢[l,r]的權值; 權值計算方法區間某個數x的個數cnt那麽貢獻為cnt*cnt*x; 所有貢獻和即為該區間的值;

code ++ 計算方法 equal ati contains tdi ces sum D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input st