leetcode 链表所有题目

来源:互联网 发布:api原油库存数据预测 编辑:程序博客网 时间:2024/05/21 06:33

简单题目

141 判断一个链表是否有环   使用快慢指针

class Solution {  public:      bool hasCycle(ListNode *head) {          ListNode* pFast=head;          ListNode* pSlow=head;          if(head==NULL) return false;          while(pFast!=NULL)          {              pSlow=pSlow->next;              pFast=pFast->next;              if(pFast==NULL) return false;              pFast=pFast->next;              if(pFast==NULL) return false;              if(pFast==pSlow) return true;          }      }  };

237 删除链表中的指定节点

给定链表中的一个节点,将这个节点删除。单链表的特点是:不能找到前驱结点,本题的方法是,将下一个节点的值复制到当前节点,然后跳过下一个节点。

class Solution {  public:      void deleteNode(ListNode* node) {          if (node==NULL) return;          else          {              node->val=node->next->val;              node->next=node->next->next;          }      }  }; 

83.在排序链表中删除重复的节点

Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

方法1:使用一个循环,循环判断cur->next,之前需要判断head是否为空

class Solution {  public:      ListNode* deleteDuplicates(ListNode* head) {         ListNode* cur=head;         if(head==NULL) return head;         while(cur->next)         {             if(cur->next->val==cur->val)             cur->next=cur->next->next;             else             cur=cur->next;         }         return head;      }  };  
方法2:循环判断当前节点

class Solution {  public:      ListNode* deleteDuplicates(ListNode* head) {         ListNode* cur=head;         while(cur)         {             while(cur->next&&cur->next->val==cur->val)             cur->next=cur->next->next;             cur=cur->next;         }         return head;      }  };  
方法3:递归版本

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;      }  }; 

160. Intersection of Two Linked Lists 找到两个链表的公共节点

A:          a1 → a2                   ↘                     c1 → c2 → c3                   ↗            B:     b1 → b2 → b3

方法1:先求两个链表的长度,然后让唱的指针先走掉长出的部分,最后两个链表一起走指针。时间复杂度为O(m+n),空间复杂度是1。

class Solution {  public:      ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {          if(headA==NULL||headB==NULL) return NULL;          unsigned int lengthA=getLength(headA);          unsigned int lengthB=getLength(headB);          ListNode *pA=headA,*pB=headB;          if(lengthA<lengthB)         {              int clap=lengthB-lengthA;          while(clap!=0){          headB=headB->next;          clap--;}         }         else {             int clap=lengthA-lengthB;             while(clap!=0){             headA=headA->next;             clap--;}         }         while(headA!=headB&&headA!=NULL&&headB!=NULL)         {             headA=headA->next;             headB=headB->next;         }         return headA;        }      unsigned int getLength(ListNode* pcurrent)//长度计算函数      {          ListNode* p=pcurrent;          unsigned int length=0;          while(p!=nullptr)          {              ++length;              p=p->next;          }          return length;      }  };  

 206 翻转链表

方法一:自己想的,初级想法
/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* reverseList(ListNode* head) {
//注意处理开头部分和特殊情况        if(head==NULL||head->next==NULL) return head;        ListNode* pNext=head->next;        if(pNext->next==NULL) {            pNext->next=head;            head->next=NULL;            return pNext;        }        ListNode* pNextNext=pNext->next;        head->next=NULL;        pNext->next=head;        while(pNextNext!=NULL)        {            ListNode* pTemp=pNextNext->next;            pNextNext->next=pNext;            pNext=pNextNext;            pNextNext=pTemp;        }               return pNext;            }};

方法2:预设0表头,并添加另外一个指针,用这两个头指针操作后续节点
class Solution {public:    ListNode* reverseList(ListNode* head) {        //使用pre零头结点和cur原来的头结点处理链表,这个程序全程pre和cur都没有变,变的是他们指向的子节点        ListNode* pre=new ListNode(0);//新建零表头        pre->next=head;        ListNode* cur=head;        while(cur&&cur->next)        {            ListNode* temp=pre->next;//用一个指针存储需要被指向的父节点            pre->next=cur->next;//pre指向原来的子节点            cur->next=cur->next->next;//cur指向子节点的下一个节点,可能是空的            pre->next->next=temp;//将子节点的下一个节点指向存储好的父节点位置temp,这里不能指向cur,因为cur保存的永远是原来的第一个头结点        }        //当cur头指向的下一个子节点是空节点时        return pre->next;            }};

方法3:使用三个指针,循环操作,pre是当前节点的前一个节点,如果当前节点时头结点,pre预设为NULL,head是当前节点,next是head的下一个节点
class Solution {public:    ListNode* reverseList(ListNode* head) {       ListNode* pre=NULL;        while(head){            ListNode* next=head->next;            head->next=pre;            pre=head;            head=next;        }        return pre;    }};
方法4:使用递归,找到最后一个节点,每层递归都是把当前节点的子节点的next指向当前节点,当前节点指向空,不会存在丢失现象,因为递归的层次保留了节点的指向信息。注意书写递归函数的返回位置和返回值是很很重要的。
class Solution {public:    ListNode* reverseList(ListNode* head) {      if(head==NULL||head->next==NULL) return head;//考虑head是空的情况,这句目的是找到最后一个节点        ListNode* cur=reverseList(head->next);        //递归的根节点时,cur得到的是当前head的子节点        head->next->next=head;        head->next=NULL;        return cur;//cur保存最后的尾节点    }};

234  Palindrome Linked List 回文链表

自己想的方法,结果不对
class Solution {public:    bool isPalindrome(ListNode* head) {        //自己想的方法,使用递归的形式,参照206中的递归方法        ListNode* pCur=head;           return comP(head,pCur,0);    }    bool comP(ListNode* head,ListNode* pCur,int count){                if(pCur==NULL||pCur->next==NULL) {            length=count;            return true;        }        count++;        bool tempdecide=comP(head,pCur->next,count);        if(tempdecide==false) return false;        count--;        if(count*2<length) return tempdecide;        if(head->val==pCur->next->val){            head=head->next;            return true;        }        else return false;            }    private:    int length;    };
方法1:
(1)使用快慢指针,让快指针指向最后一个节点,慢指针指向中间位置;
(2)对慢指针进行操作,慢指针之后的链表做翻转操作(第206道题);
(3)相当于将原来的指针分成两个指针,然后依次比较两个指针每个值的大小,开始的链表从原来的头部比较
(4)比较的时候,当后面的链表结束的时候,比较结束,当原链表长度是奇数时,前面的链表最后一个节点不参与比较;
class Solution {public:    bool isPalindrome(ListNode* head) {     if(head==NULL||head->next==NULL) return true;        ListNode* slow=head;        ListNode* fast=head;        //让快指针运动到最后,这时如果是偶数个,慢指针指向中间偏左的节点,如果是奇数个,慢指针指向中间的节点        while(fast->next&&fast->next->next)        {            slow=slow->next;            fast=fast->next->next;        }        slow->next=reverseList(slow->next);        slow=slow->next;        while(slow){            if(slow->val!=head->val) return false;            slow=slow->next;            head=head->next;        }        return true;    }    //翻转链表,使用206第三种方法    ListNode* reverseList(ListNode* head){        ListNode* pre=NULL;        ListNode* next=NULL;        while(head){           next=head->next;            head->next=pre;             pre=head;            head=next;          }        return pre;    }};

方法3:递归调用,递归函数的返回值是布尔型,每次判断的结果是回调的结果与当前比较的与。注意,在类中定义一个指针用于保存初始头结点,相当于全局变量。

class Solution {public:    ListNode* temp;    bool isPalindrome(ListNode* head) {        if(head==NULL) return true;        temp=head;        return check(head);    }    bool check(ListNode* head){        if(head==NULL) return true;        bool tempcheck=check(head->next)&(temp->val==head->val);        temp=temp->next;        return tempcheck;    }};

21 合并两个排序链表 merge two linked list

方法1:自己写的方法,
(1)设置一个头指针,开始时指向较小的那个节点
(2)然后进入循环,每次指向较小的节点,并且被并入的节点对应的链表后移一个。
(3)要注意两个链表不一样长的时候,在结尾需要做处理。

class Solution {public:    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        if(l1==NULL) return l2;        if(l2==NULL) return l1;        ListNode* prehead=new ListNode(0);         if(l1->val<l2->val)        {            prehead->next=l1;            l1=l1->next;        }        else        {            prehead->next=l2;            l2=l2->next;        }         ListNode* temp=prehead->next;        while(l1&&l2){             if(l1->val<l2->val)        {            temp->next=l1;            l1=l1->next;        }        else        {            temp->next=l2;            l2=l2->next;        }             temp=temp->next;        }        if(l1==NULL)            temp->next=l2;        else            temp->next=l1;        return prehead->next;            }};

方法2:递归方法

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(l2->next,l1);            return l2;        }            }};
方法3:
方法1的改进版本。
一方面,可以把开始的部分合并,方法是做一个头指针的拷贝,开始关于是否有空指针的判断也可以省略不写。另一个方面,最后的判断可以使用条件语句快速写出。
class Solution {public:    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        ListNode* prehead=new ListNode(0);        ListNode* head=prehead;        while(l1&&l2){             if(l1->val<l2->val)        {            prehead->next=l1;            l1=l1->next;        }        else        {            prehead->next=l2;            l2=l2->next;        }             prehead=prehead->next;        }       prehead->next=l1?l1:l2;        return head->next;     }};

中等难度


61 Rotate List 

描述:给定一个链表,在链表的倒数第k个位置旋转链表

Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.

方法:先让一个指针移动k-1步,然后和另外一个头指针一起移动,当最前面的指针移动到末尾时,后面的指针正好移动到旋转位置;
注意要保存后一个指针的前一个指针,还要保存头指针。

自己写的:出现很多的调试错误
class Solution {public:    ListNode* rotateRight(ListNode* head, int k) {        if(head==NULL||k<=0) return head;        ListNode* frontNode=head;        //如果k的值大于链表长度怎么办?        --k;        while(k&&frontNode!=NULL)        {            frontNode=frontNode->next;             k--;        }        if(frontNode==NULL) return head;        ListNode* backNode=head;        ListNode* tempNode=head;        while(frontNode->next){            frontNode=frontNode->next;            tempNode=backNode;            backNode=backNode->next;        }        if(backNode==head) return head;        frontNode->next=head;        tempNode->next=NULL;        return backNode;    }};
方法1: 首先遍历一边求出总的长度,并把链表编程环,然后根据整除数对链表做操作
class Solution {public:    ListNode* rotateRight(ListNode* head, int k) {      if(!head) return NULL;        int length=1;        ListNode* tail=head;        while(tail->next){            tail=tail->next;            length++;        }        tail->next=head;//变成环状链表        if(k%=length)//对移动k数取余数        {            for(auto i=0;i<length-k;i++) tail=tail->next;//让tail从尾节点移动到旋转节点的前一个节点        }        ListNode* newHead=tail->next;        tail->next=NULL;        return newHead;    }};

143 recorder List

Given a singly linked list LL0?L1?…?Ln-1?Ln,
reorder it to: L0?Ln?L1?Ln-1?L2?Ln-2?…

You must do this in-place without altering the nodes' values.

For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.

交叉更改链表顺序,但是不能直接改变数值

我的思路:使用快慢指针,将后半段链表翻转,使用前面回文串的思路,然后与第一个链表交叉起来。

这个思路与标准思路一致

class Solution {public:    void reorderList(ListNode* head) {        if(head==NULL) return ;        ListNode* fast=head;        ListNode* slow=head;        while(fast->next&&fast->next->next){//注意判断条件,需要后面两个子节点都判断            fast=fast->next->next;            slow=slow->next;        }        //操作slow指针后面的链表,将其翻转        slow->next=reverseNode(slow->next);        //将链表截断,slow指向空,然后新的slow指向后面的翻转链表        ListNode* tail=slow;        slow=slow->next;        tail->next=NULL;        //下面将两个链表合并到一起,注意末尾操作的特殊性        ListNode* newHead=head;        while(slow)//注意判断条件决定最后末尾的操作,head的长度可能比slow多一位        {            ListNode* next1=head->next;            ListNode* next2=slow->next;            head->next=slow;            slow->next=next1;            slow=next2;            head=next1;        }        return ;    }    //翻转链表的函数    ListNode* reverseNode(ListNode* head){        //使用pre、head、next三个指针        ListNode* pre=NULL;        ListNode* next=NULL;        while(head)//注意这里的判断条件,决定末尾的情况。一定不能出现空指针next操作        {            next=head->next;            head->next=pre;            pre=head;            head=next;        }        return pre;    }};

142Linked List Cycle II 环状链表2

给定一个链表,返回链表环开始的节点,如果没有环,返回null。
分析:http://blog.csdn.net/wuzhekai1985/article/details/6725263
class Solution {public:    ListNode *detectCycle(ListNode *head) {        if(head==NULL) return head;        ListNode* fast=head;        ListNode* last=head;        while(fast->next&&fast->next->next)//注意需要先判断fast->next,因为必须满足这一点才能继续往下判断        {            last=last->next;            fast=fast->next->next;            if(last==fast) break;                    }        if(fast->next==NULL||fast->next->next==NULL) return NULL;        while(true){            if(head==last) break;            head=head->next;            last=last->next;        }        return head;    }};

138Copy List with Random Pointer26.3%Medium

给出的链表在正常链表的基础上,每个节点还有一个随机指针指向此链表的一个节点,题目要求返回这个链表的一个拷贝
拷贝需要新建节点,难点在于怎么处理各节点之间的随机关系
思路:
(1)在原链表每个节点后面插入一个链表,并拷贝相应的值
(2)随机指针的处理,只要将新节点的随即指针指向它前面节点随机指针的下一个即可
(3)最后将链表拆解开
class Solution {public:    RandomListNode *copyRandomList(RandomListNode *head) {               if(head==NULL) return NULL;        RandomListNode* headCopy=head;//复制原来的头结点         //第一步,在每个节点后面复制一个相同数值的节点        while(head){            RandomListNode* newNode=new RandomListNode(head->label);            RandomListNode* next=head->next;            head->next=newNode;            newNode->next=next;            head=next;        }        //第二步,处理随机指针,将每个新节点的random指针指向,它前面节点random指针指向的下一个节点        RandomListNode* newHead=headCopy->next;        RandomListNode* headCopyCopy=headCopy;        while(headCopy){            newHead->random=headCopy->random?headCopy->random->next:NULL;//注意random不一定指向一个节点,有可能是空值            headCopy=headCopy->next->next;            if(headCopy==NULL) break;            newHead=newHead->next->next;//当到达尾部时,newHead处于结尾,这个语句将产生错误,所以需要在前面退出程序        }        //第三步,分解现在的链表        headCopy=headCopyCopy;        newHead=headCopy->next;        while(headCopy&&headCopy->next&&headCopy->next->next){            RandomListNode* middle=headCopy->next;            RandomListNode* last=middle->next;            headCopy->next=last;            headCopy=middle;            }        headCopy->next=NULL;        return newHead;    }};

https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking   这是牛客网上自己写的另外一个版本

92Reverse Linked List II   倒置链表 2

206的增进版本,截取链表的m到n的部分,翻转链表,在原来位置上改动,不允许额外的空间,要求一次完成
例如:

Given 1->2->3->4->5->NULLm = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:
Given mn satisfy the following condition:

1 ≤ m ≤ n ≤ length of list.

自己的思路:与前面的206没有太大的区别,需要注意的几点是:

(1)应该设置表头指针,这样能处理第一个节点就参与旋转的情况;

(2)注意要设置多个指针保存中间段的入口和出口一共四个节点;

(3)m和n相等的情况是特殊的,在程序开始时直接处理。

class Solution {public:    ListNode* reverseBetween(ListNode* head, int m, int n) {         if(head==NULL||m==n) return head;               ListNode* preHead=new ListNode(-1);//表头指针        ListNode* result=preHead;        preHead->next=head;//表头指针指向原来的头结点,这能解决开始头结点就需要旋转的情况        ListNode* frontEntry=NULL;//保存入口之前的节点        //需要表头指针         for(int i=0;i<m;i++)         {             frontEntry=preHead;             preHead=preHead->next;          }        //下面旋转节点,采用三节点法,三个指针依次是preNode、preHead、next        ListNode* preNode=NULL;        ListNode* frontNode=preHead;//保存入口节点        for(int i=0;i<n-m+1;i++){            ListNode* next=preHead->next;            preHead->next=preNode;            preNode=preHead;//注意            preHead=next;//注意这两行的顺序                    }        //此时preNode指向出口节点,preHead指向出口节点的下一个节点        frontEntry->next=preNode;//原来的入口指向中间新的头部        frontNode->next=preHead;//中间新段的尾部指向后来剩余的头部        return result->next;    }};

19Remove Nth Node From End of List33.3%Medium

将一个链表的倒数第n个节点去除,返回链表的头结点

Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.

主要的难点是删除的点是第一个时怎么操作,采取的办法是认为的定义一个头结点指向原来的头结点。

方法1,代码如下:

class Solution {public:    ListNode* removeNthFromEnd(ListNode* head, int n) {        //如果移除的是第一个节点,呵呵        //考虑这种特殊的情况,需要定义一个头结点指向原来的头结点,这样就能解决删除第一个节点的情况了        ListNode* newHead=new ListNode(0);        newHead->next=head;        ListNode * fast =newHead,* slow=newHead;        for(int i=0;i<n;i++)            fast=fast->next;        while(fast->next)        {            slow=slow->next;            fast=fast->next;        }        ListNode* toBeDelete=slow->next;        slow->next=slow->next->next;        delete toBeDelete;        return newHead->next;    }};

Add Two Numbers  27.6%Medium

描述:两个链表存储每一位数,求加和的新链表
要求:争取一次遍历成功

自己的代码:有错崩溃

class Solution {public:    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        //注意两个链表的长度可能不一样长       int addNumber=0;        ListNode* cl1=l1,* cl2=l2,* tempNode=l1;        while(cl1&&cl2)        {            int temp=cl1->val+cl2->val+addNumber;            if(temp>9){        addNumber=1;            cl1->val=temp-10;            }            else{                addNumber=0;                cl1->val=temp;            }            tempNode=cl1;            cl1=cl1->next;            cl2=cl2->next;                    }        if(cl1==NULL&&cl2!=NULL)        {            tempNode->next=cl2;        }                  while(tempNode)            {                int temp=tempNode->val+addNumber;//有错                if(temp>9){        addNumber=1;            tempNode->val=temp-10;            }            else{                addNumber=0;                tempNode->val=temp;            }                            cl1=tempNode;            tempNode=tempNode->next;            }        if(addNumber==1)        {            ListNode* temp=new ListNode(1);            cl1->next=temp;        }        return l1;    }};

方法:新建一个链表,在循环中单独判断两个链表是否为空,使用sum保存每次的加和,并在链表中保存余数,在下一次循环中,这个sum值的起始值是除10后的数。

class Solution {public:    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {      ListNode *c1=l1;        ListNode *c2=l2;        ListNode * result=new ListNode(0);        ListNode* tempNode=result;        int sum=0;        while(c1||c2)        {            sum/=10;            if(c1)            {                sum+=c1->val;                c1=c1->next;            }            if(c2){                sum+=c2->val;                c2=c2->next;            }            tempNode->next=new ListNode(sum%10);            tempNode=tempNode->next;        }        if(sum>9)        {            tempNode->next=new ListNode(1);        }        return  result->next;    }};

另外一种方法:使用条件运算符简化代码

class Solution {public:    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {      ListNode* p=new ListNode(0);        ListNode * temp=p;        int extra=0;        while(l1||l2||extra){            int sum=extra+(l1?l1->val:0)+(l2?l2->val:0);            extra=sum/10;            temp->next=new ListNode(sum%10);            temp=temp->next;            l1=l1?l1->next:l1;            l2=l2?l2->next:l2;        }        return p->next;    }};

445Add Two Numbers II46.1%Medium

描述:这个题目是增进版本,高位数在前面,低位数在后面

Example:

Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)Output: 7 -> 8 -> 0 -> 7

24Swap Nodes in Pairs38.2%Medium

给定一个链表,交换两个相邻的节点

只能使用常数空间,不能更改节点的值
Given 1->2->3->4, you should return the list as 2->1->4->3.
思路:
因为第一个节点会变,所以设置表头指针。
由于奇偶性不同,一次循环需要处理两个节点。
如果是奇数个,最后一个节点不动。
自己写的代码: 题目比较简单,主要是考虑每次循环如何处理(要做三次指针操作,并且保存下一次循环的指针p)
class Solution {public:    ListNode* swapPairs(ListNode* head) {        if(head==NULL) return head;        ListNode* preHead=new ListNode(0);        preHead->next=head;        ListNode* p=preHead;        while(p->next&&p->next->next){            ListNode* next=p->next;            ListNode* nextNext=next->next;            ListNode* third=nextNext->next;            p->next=nextNext;            nextNext->next=next;            next->next=third;            p=next;        }        return preHead->next;    }};


86Partition List 32.5%Medium 类似快速排序

给定一个数,将链表重新排序
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
自己的思路:设置两个指针,分别指向小于指定数和大于指定数。当遍历完成之后,合并两个链表。
小链表要保存头部作为所有的头,大链表也要保存头部与小链表的尾部相连,大链表的为节点需要指向NULL。
如果所有的值都小于这个数,和所有值都大于这个数,程序也可以正常执行
class Solution {public:    ListNode* partition(ListNode* head, int x) {        if(head==NULL) return head;        ListNode* small=new ListNode(-1);        ListNode* big=new ListNode(-1);        ListNode* smallCopy=small;        ListNode* bigCopy=big;        while(head){            if(head->val<x){                smallCopy->next=head;                smallCopy=head;            }            else            {                bigCopy->next=head;                bigCopy=head;            }            head=head->next;        }        bigCopy->next=NULL;        smallCopy->next=big->next;        delete big;        delete small;        return small->next;    }};
别人的思路基本一致。

82Remove Duplicates from Sorted List II29.4%Medium

给定一个排序链表,去除链表中所有重复的数,注意重复的数字全部去除。与版本I不同,版本1是留下一个重复的数字。
自己的思路:设置起始头结点,它所指向的数必须和后面的数不同。编不下去喽
看别人的思路使用递归

放一放吧

328Odd Even Linked List 43.4%Medium

将一个链表原来处在奇数位置的节点放到前面,偶数位置的节点放到后面
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
自己的思路:与86题思路类似,设置两个表头指针odd和even,分别指向奇数和偶数节点,完成后将奇数节点的尾节点指向偶数的头结点。
class Solution {public:    ListNode* oddEvenList(ListNode* head) {        ListNode* preOdd=new ListNode(-1);        ListNode* preEven=new ListNode(-1);        ListNode* odd=preOdd;        ListNode* even=preEven;        bool oddOrEven=true;//奇数为true,偶数为false        while(head){            if(oddOrEven){                odd->next=head;                odd=head;                oddOrEven=false;            }            else{                even->next=head;                even=head;                oddOrEven=true;            }            head=head->next;        }        even->next=NULL;        odd->next=preEven->next;        return preOdd->next;    }};

109Convert Sorted List to Binary Search Tree  33.8%Medium


148 sort list  

将一个链表排序,要求时间复杂度是O(n log n),空间复杂度是1.
使用归并排序
147 insertion sort list  
使用直接插入排序将一个链表排序。

25. Reverse Nodes in k-Group

自己写的代码:
class Solution {public:    ListNode* reverseKGroup(ListNode* head, int k) {        ListNode* last=head;        ListNode*newHead=new ListNode(0);        newHead->next=head;        ListNode* first=newHead;        int n=1;        while(last)        {            if(n==k) {//如果收集到了k个节点                ListNode* pre=last->next;                ListNode* temp=first->next;                ListNode* nowHead=first->next;                while(n)                {                    ListNode* next=nowHead->next;                    nowHead->next=pre;                    pre=nowHead;                    nowHead=next;                    n--;                }                n=1;                first->next=pre;                first=temp;                last=first->next;                continue;            }            last=last->next;            n++;        }        n--;        return newHead->next;    }         };






原创粉丝点击