刷题笔记:链表

重排链表(1->n->2->(n-1)->3.....)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode* head) {
         if (!head || !head->next || !head->next->next) //节点数 <= 2
        {
            return;
        }

        //找后面待插入的节点
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }

        //反转后部分
        ListNode* head1 = slow->next;
        slow->next = nullptr; //新链表的尾
        head1 = reverse_list(head1);

        //插入到前部分
        while (head1)
        {
            ListNode* next = head->next;
            ListNode* next1 = head1->next;
            head1->next = next;
            head->next = head1;
            head = next;
            head1 = next1;
        }
    }

    ListNode* reverse_list(ListNode* head)
    {
        ListNode* prev = nullptr;
        ListNode* cur = head;

        while (cur)
        {
            ListNode* next = cur->next;
            cur->next = prev;
            prev = cur;
            cur = next;
        }

        return prev;
    }
    
};

反转链表

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* result=NULL;
        while(head)
        {
            ListNode* temp=head->next;
            head->next=result;
            result=head;
            head=temp;
        }
        return result;
    }
};

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* pre0,*cur0;
        unsigned int count = 1;
        while(cur != NULL && count <= n){
            //当cur为m时,记录一下当前cur和pre
            if(count == m)//在头节点,则记录当前pre和cur供后续连接使用
            {
                pre0 = pre;
                cur0 = cur;
            }
            //当cur在(m,n]之间时,反转链表
            if(count > m && count <= n)
            {
                ListNode* temp = cur->next;
                cur->next = pre;
                pre = cur;
                cur = temp;
            }
            else         //常规迭代处理
            {
                pre = cur;
                cur = cur->next;
            }
            //常规处理
            ++count; 
        }
        //最后的链接操作
        //将pre0的next指向第n元素,此时pre指向n,cur指向原始链表中n的下一个元素
        if(pre0 == NULL) head = pre;
        else pre0->next = pre;
        //将指向m的cur0的next指向n后第一个元素
        cur0->next = cur;

        return head;
    }
};

链表求环

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast=head;
        ListNode* slow=head;
        ListNode* meet=NULL;
        while(fast){
            slow=slow->next;
            fast=fast->next;
            if(!fast){
                return NULL;        
            }
            fast=fast->next;
            if(fast==slow){
                meet=fast;
                break;
            }
        }
        if(meet==NULL){
            return NULL;
        }
        while(head && meet ){
            if(head==meet){
                return head;
            }
            head=head->next;
            meet=meet->next;
        }
        return NULL;
    }
};

链表按大小划分

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode less(0);
        ListNode more(0);
        ListNode* lessPtr=&less;
        ListNode* morePtr=&more;
        if(!head)
        {
            return NULL;
        }
        while(head)
        {
            if(head->val < x)
            {
                lessPtr->next=head;
                lessPtr=lessPtr->next;
            }
            else
            {
                morePtr->next=head;
                morePtr=morePtr->next;
            }
            head=head->next;
        }
        lessPtr->next=more.next;
        morePtr->next=NULL;
        return less.next;
        
    }
};

 

随机链表得深拷贝

class Solution {
public:
    Node* copyRandomList(Node* head) {
        map<Node*,int> map1;
        vector<Node*> map2;
        Node* head1=head;
        if(!head1)
        {
            return NULL;
        }
        int i=0;
        while(head1)
        {
            //新增结点
            map2.push_back(new Node(head1->val));
            //原链表对应关系存入map1
            map1[head1]=i; 
            head1=head1->next;    
            i++;
        }
        head1=head;
        i=0;
        map2.push_back(0);
        while(head1)
        {
            map2[i]->next=map2[i+1];   
            if(head1->random)
            {
                map2[i]->random=map2[map1[head1->random]];
            }     
            head1=head1->next;
            i++;   
        }
        return map2[0];

    }
};

合并排序后得链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode temp_head(0);
        ListNode *pre=&temp_head;
        while(l1 && l2){
            if(l1->val < l2->val){
                pre->next=l1;
                l1=l1->next;
            }
            else{
                pre->next=l2;
                l2=l2->next;
            }
            pre=pre->next;
        }
        if(l1){
            pre->next=l1;
        }
        if(l2){
            pre->next=l2;
        }

        return temp_head.next;
    }
};

合并多个排序链表

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
      if(lists.size()==0)
      {
          return NULL;
      }
      if(lists.size()==1)
      {
          return lists[0];
      }  
      if(lists.size()==2)
      {
          return mergeTwoLIsts(lists[0],lists[1]);
      }
      int mid=lists.size()/2;
      vector<ListNode*> sub_lis1,sub_lis2;
      for(int i=0;i<mid;i++)
      {
          sub_lis1.push_back(lists[i]);
      }
      for(int i=mid;i<lists.size();i++)
      {
          sub_lis2.push_back(lists[i]);
      }

    ListNode* l1=mergeKLists(sub_lis1);
    ListNode* l2=mergeKLists(sub_lis2);
    return mergeTwoLIsts(l1,l2);

    }
private:
  ListNode* mergeTwoLIsts(ListNode* lists1,ListNode* lists2)
  {
      if(lists1==NULL)
      {
          return lists2;
      }
      if(lists2==NULL)
      {
          return lists1;
      }
      ListNode temp(0);
      ListNode* result=&temp;
      while(lists1 && lists2)
      {
          if(lists1->val < lists2->val)
          {
              result->next=lists1;
              lists1=lists1->next;
          }
          else
          {
              result->next=lists2;
              lists2=lists2->next;
          }
          result=result->next;
      }
      if(!lists1)
      {
          result->next=lists2;
      }
      if(!lists2)
      {
          result->next=lists1;
      }
      return temp.next;
  }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值