1. 程式人生 > >Reverse Linked List以及一道有關倒序的題目

Reverse Linked List以及一道有關倒序的題目

Hint:

A linked list can be reversed either iteratively or recursively. Could you implement both?

遞迴法:

/**
 * 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&&head->next){
      ListNode*p=head->next;
      head->next=nullptr;
      ListNode*newhead=reverseList(p);
      p->next=head;
      return newhead;
      }
      return head;
        
    }
};

每次把第一個節點扔到最後,迴圈到最終狀態


迭代法:

(1) Create a Node named prehead before  head and  locate the immediate node before them-th (notice that it is 1-indexed) node pre;

(2) Set cur to be the immediate node after pre and at each time move the immediate node aftercur (named move) to be the immediate node after pre

. Repeat it forn - m times.

/**
 * 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) {
        ListNode prehead(0),*pre=&prehead,*cur,*move;
        pre->next=head;
        cur=pre->next;
        while(cur&&cur->next)
        {
            move=cur->next;
            cur->next=move->next;
            move->next=pre->next;
            pre->next=move;
        }
        return prehead.next;
        
    }
};

二.

Reorder List

Given a singly linked list L: L0L1→…→Ln-1Ln,
reorder it to: L0LnL1Ln-1L2Ln-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}.

這道題我先用了遞迴的方法,結果tle了 程式碼如下
class Solution {
public:
    void reorderList(ListNode* head) {
        if(head!=nullptr&&head->next!=nullptr){
        ListNode *p=head,*tail=head->next;
        while(tail->next)
        {
            p=p->next;
            tail=tail->next;
        }
        p->next=nullptr;
        reorderList(head->next);
        tail->next=head->next;
        head->next=tail;
        }
    }
};

然後我發現了我們可以把後半部分倒序,然後插入到前半部分,就可以完成這道題目
程式碼如下:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
   
    void reorderList(ListNode* head) {
        if(head!=nullptr&&head->next!=nullptr&&head->next->next!=nullptr){
        ListNode *pre,*tail,*cur,*move;
        pre=head; tail=head;
        int sum=0;
        while(pre)
        {
            pre=pre->next;
            sum++;
        }
        pre=head;
        sum=sum/2;
        for(int i=0;i<sum-1;i++)
        pre=pre->next;
        cur=pre->next;
        while(cur->next)
        {
            move=cur->next;
            cur->next=move->next;
            move->next=pre->next;
            pre->next=move;
        }
        pre->next=nullptr;
        pre=head;
        
        while(cur!=nullptr)
        {
            cur=pre->next;
            pre->next=move;
            pre=move;
            move=cur;
            
            
        }
        
        
    }}
};