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

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;
    }
};
时间: 2024-08-29 08:07:31

【Leetcode解题报告】单链表结点位置调整的相关文章

【Leetcode解题报告】

第1章  单链表 1.1  删除单链表中的结点 203 Remove Linked List Elements 83  Remove Duplicates from Sorted List 82  Remove Duplicates from Sorted List II 19  Remove Nth Node from End of List 237 Delete Node in a Linked List 1.2  单链表结点位置调整 206 Reverse Linked List 92  

leetCode解题报告5道题(九)

题目一:Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example,If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 分析: 题意给我们一个数字n, 和一个数字k,让我们求出从 1~~n中取出k个数所能得到的组合数 所

LeetCode解题报告:Linked List Cycle &amp;&amp; Linked List Cycle II

Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using extra space? Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follo

leetCode解题报告5道题(十)

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2368    Accepted Submission(s): 333 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.磁

leetCode解题报告5道题(八)

题目一: Populating Next Right Pointers in Each Node Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the

LeetCode解题报告:Reorder List

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}. 思路: 1.利用快慢两个指针将链表一分为二: 2.针对第二个子链表求倒序

Leetcode: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}. 分析:观察重排前和重排后的序列,发现单链表前半部分各元素的相对顺序保持不变,而后半部分逆序.因

两种删除单链表结点的实现,一种O(n),一种O(1)

常规的删除单链表结点的做法是挨个查找到该结点的前一个结点,然后去掉要删除的这个结点,回收内存.这个需要O(n)的时间. 有一种比较快速的删除掉链表指定一个节点的方法,就是把下一个结点的内容复制到当前这个结点,然后把下一次结点删除掉,这个需要考虑当要删除的结点是最后一个结点的情况. 如果刚好是最后一个结点,则需要O(n)的时间,如果不是最后一个结点,可以在O(1)时间内完成删除操作. 1 // 2 // main.c 3 // SingleListDeleteNode 4 // 5 // Crea

leetCode解题报告5道题(十一)

题目一:Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2]