码迷,mamicode.com
首页 > 其他好文 > 详细

【Leetcode解题报告】单链表结点位置调整

时间:2016-07-14 08:34:22      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:

Leetcode 206 Reverse Linked List

题目描述

  Reverse a singly linked list. 

分析与解法

(1) 递归解法

  参考代码如下:

/**
 * 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) return head; 
        ListNode *cur = head, *temp = head->next, *reverse_head = reverseList(head->next); 
        temp->next = cur; 
        cur->next = NULL; 
        return reverse_head; 
    }
};

(2) 非递归解法

  参考代码如下:

/**
 * 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) return head; 
        ListNode *p = head, *q = head->next; 
        while (q)
        {
            ListNode *r = q->next; 
            q->next = p; 
            p = q; 
            q = r; 
        }
        head->next = NULL; 
        return p; 
    }
};

Leetcode 92 Reverse Linked List II

题目描述

  Reverse a linked list from position m to n. Do it in-place and one-pass. For example, given 1 -> 2 -> 3 -> 4 -> 5 -> NULL, m = 2 and n = 4. Return 1 -> 4 -> 3 -> 2 -> 5 -> NULL. Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list. 

分析与解法

  先找到第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) 
    {
        if (!head || !head->next || m == n) return head; 
        ListNode *nhead = new ListNode(0); nhead->next = head; 
        ListNode *pb = nhead, *pe = head; 
        int i = 1; 
        while (i < m)
        {
            i++; 
            pb = pb->next; 
            pe = pe->next; 
        }
        while(i <= n) 
        {
            i++; 
            pe = pe->next; 
        }
        ListNode *p = pb->next, *q = p->next; 
        p->next = pe; 
        while (q != pe)
        {
            ListNode *r = q->next; 
            q->next = p; 
            p = q; 
            q = r; 
        }
        pb->next = p; 
        return nhead->next; 
    }
};

Leetcode 328 Old Even Linked List

题目描述

  Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. You should try to do it in place. The program should run in O(1) space comlexity and O(nodes) time complexity. For example, given 1 -> 2 -> 3 -> 4 -> 5 -> NULL, return 1 -> 3 -> 5 -> 2 -> 4 -> NULL.

  Note: The relative order inside both the even and odd groups should remain as it was in the input. The first node is considered odd, the second node even and so on. 

分析与解法

  创建新的链表头结点,分别为odd_head、even_head,将odd结点依次插入到odd_head表中,将even结点依次插入到even_head表中,最后将odd表与even表链接起来即可。参考代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) 
    {
        if (!head || !head->next) return head; 
        ListNode odd_head(0), even_head(0); 
        ListNode *odd_cur, *even_cur; 
        odd_head.next = head; odd_cur = head; even_head.next = head->next; even_cur = head->next; 
        int cnt = 0; 
        for (ListNode *p = head->next->next; p != NULL; p = p->next)
        {
            odd_cur->next = p; 
            odd_cur = p; 
            p = p->next; 
            even_cur->next = p; 
            even_cur = p; 
            if (p == NULL) break;
        }
        odd_cur->next = even_head.next; 
        return odd_head.next; 
    }
};

Leetcode 143 Reorder List

题目描述

  Given a singly linked list L: L0 -> 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}.  

分析与解法

  先使用快慢指针找到链表的中间结点,将链表分为两部分;然后将链表的后半部分逆置;最后将后半部分依次插入到前半部分中即可。由此可见,复杂的问题其实就是几个简单问题的叠加。参考代码如下所示:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    ListNode *reverse(ListNode *head) // 单链表逆置
    {
        if (!head || !head->next) return head; 
        ListNode *cur = head, *tmp = head->next; 
        ListNode *new_head = reverse(head->next); 
        tmp->next = cur; cur->next = NULL; 
        return new_head; 
    }
public:
    void reorderList(ListNode* head) 
    {
        if (!head || !head->next) return; 
        ListNode *nhead = new ListNode(0); nhead->next = head; 
        ListNode *p = nhead, *q = head; 
        while (q)
        {
            p = p->next; q = q->next; 
            if (q) q = q->next; 
        }
        ListNode *tail = p->next; 
        p->next = NULL; p = head; 
        tail = reverse(tail); 
        while (tail)
        {
            ListNode *r = tail->next; 
            tail->next = p->next; 
            p->next = tail; 
            p = tail->next; 
            tail = r; 
        }
    }
};

Leetcode 24 Swap Nodes in Pairs

题目描述

  Given a linked list, swap every two adjacent nodes and return its head. For example, given 1 -> 2 -> 3 -> 4, you should return the list as 2 -> 1 -> 4 -> 3. You algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. 

分析与解法

(1) 非递归解法

  参考代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) 
    {
        if (!head || !head->next) return head; 
        ListNode *nhead = new ListNode(0), *p = nhead, *q = head; 
        nhead->next = head; 
        while (q && q->next)
        {
            ListNode *r = q->next, *s = r->next; 
            p->next = r; 
            r->next = q; 
            q->next = s; 
            p = q; 
            q = s; 
        }
        return nhead->next; 
    }
};

(2) 递归解法

  参考代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) 
    {
        if (!head || !head->next) return head; 
        ListNode *p = head, *q = head->next; 
        p->next = swapPairs(q->next); 
        q->next = p; 
        return q; 
    }
};

 (3) 这是一个不符合题意的解法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) 
    {
        ListNode *p = head; 
        while (p && p->next)
        {
            swap(p->val, p->next->val); 
            p = p->next->next; 
        }
        return head; 
    }
};

Leetcode 25 Reverse Nodes in k-Group

问题描述

  Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nodes itself may be changed. Only constant memory is allowed. For example, given this linked list: 1 -> 2 -> 3 -> 4 -> 5. For k = 2, you should return: 2 -> 1 -> 4 -> 3 -> 5; For k = 3, you should return 3 -> 2 -> 1 -> 4 -> 5. 

分析与解法

(1) 递归

  参考代码如下所示

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) 
    {
        if (!head || !head->next || k < 2) return head; 
        ListNode *next_group = head; 
        for (int i = 0; i < k; i++)
        {
            if (next_group) next_group = next_group->next; 
            else return head; 
        }
        ListNode *new_next_group = reverseKGroup(next_group, k); 
        ListNode *prev = NULL, *cur = head; 
        while (cur != next_group)
        {
            ListNode *next = cur->next; 
            cur->next = prev ? prev : new_next_group; 
            prev = cur; 
            cur = next; 
        }
        return prev; 
    }
};

(2) 非递归

  参考代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    ListNode *reverse(ListNode *prev, ListNode *begin, ListNode *end)
    {
        ListNode *end_next = end->next, *p = begin, *cur = p->next; 
        while (cur != end_next)
        {
            ListNode *next = cur->next; 
            cur->next = p; 
            p = cur; 
            cur = next; 
        }
        begin->next = end_next; 
        prev->next = end; 
        return begin; 
    }
    
public:
    ListNode* reverseKGroup(ListNode* head, int k) 
    {
        if (!head || !head->next || k < 2) return head; 
        ListNode *nhead = new ListNode(0); nhead->next = head; 
        for (ListNode *prev = nhead, *end = head; end; end = prev->next)
        {
            for (int i = 1; i < k && end; i++) end = end->next; 
            if (!end) break;
            prev = reverse(prev, prev->next, end); 
        }
        return nhead->next; 
    }
};

【Leetcode解题报告】单链表结点位置调整

标签:

原文地址:http://www.cnblogs.com/xiaoxxmu/p/5642270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!