62. 链表重排[Reorder List]

【本文链接】

http://www.cnblogs.com/hellogiser/p/reorder-list.html

【题目】

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,5,6,7}, reorder it to {1,7,2,6,3,5,4}.

【分析】

题目思路比较直接:

(1)找到链表的中间节点,把链表划分成2个子链表;如果原链表长度为奇数,那么第一个子链表的长度多1;

(2)翻转第二个子链表;

(3)交叉合并两个子链表。

例如{1,2,3,4,5,6,7}

(1)找到链表的中间节点为4,把链表划分成2个子链表:{1,2,3,4}和{5,6,7};

(2)翻转第二个子链表得到{7,6,5}

(3)交叉合并{1,2,3,4}和{7,6,5}得到{1,7,2,6,3,5,4}

【代码】

C++
Code






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

 

// 62_ReorderList.cpp : Defines the entry point for the console application.

//
/*
     version: 1.0

     author: hellogiser

     blog: http://www.cnblogs.com/hellogiser

     date: 2014/5/30
*/

#include "stdafx.h"


struct ListNode

{
    int value;

     ListNode *next;
};

// find middle node of list

ListNode *FindMiddleNode(ListNode *head)

{
    if(NULL == head)

        return NULL;

     ListNode *fast = head, *slow = head;

    while(fast != NULL && fast->next != NULL)

     {

        // move fast 2 steps

        fast = fast->next->next;

        if (fast == NULL)

            break;

        // move slow 1 step

        slow = slow->next;

     }
    return slow;
}

// reverse list

ListNode *ReverseList(ListNode *head)

{
    if(NULL == head || NULL == head->next)

        return head;

     ListNode *prev = NULL, *cur = head, *next = NULL;

    while(cur != NULL)

     {

        // save next

        next = cur->next;

        // reverse

        cur->next = prev;

        // update prev and cur

        prev = cur;

         cur = next;

     }
    return prev;
}

// cross merge list

ListNode *CrossMergeList(ListNode *head1, ListNode *head2)

{
    if(NULL == head1)

        return head2;

    else if (NULL == head2)

        return head1;

     ListNode *node1 = head1, *node2 = head2;

    while(node2 != NULL)

     {

         ListNode *temp1 = node1->next;

         ListNode *temp2 = node2->next;

         node1->next = node2;

         node2->next = temp1;

        // update node1 node2

        node1 = temp1;

         node2 = temp2;

     }
    return head1;
}

// reorder list

ListNode *ReOrderList(ListNode *head)

{
    if(NULL == head || NULL == head->next)

        return head;

    // find middle node of list

    ListNode *middle = FindMiddleNode(head);

    // split into 2 lists

    ListNode *head1 = head;

     ListNode *head2 = middle->next;

    // detach the 2 lists

    middle->next = NULL;

    // reverse list2
    head2 = ReverseList(head2);

    // cross merge 2 lists

    return CrossMergeList(head1, head2);

}

【参考】

http://blog.csdn.net/whuwangyi/article/details/14146461

【本文链接】

http://www.cnblogs.com/hellogiser/p/reorder-list.html

时间: 2024-10-10 07:47:12

62. 链表重排[Reorder List]的相关文章

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}. 刚看到题目,第一个冒出来的想法如下: 对应程序如下: 1 /** 2 *

LeetCode 143题:Reorder List的分析及两种解题思路

特别说明:参考了很多前辈的文章,整理如下,我只做了重新编码的工作,不能保证代码最优,主要用作交流学习. 题目: 方法1:将链表的每个节点地址保存在指针数组中,利用数组随机访问调整链表. 1 struct ListNode 2 { 3 int val; 4 ListNode *next; 5 ListNode(int x) : val(x), next(NULL) {} 6 }; 7 8 void reorderList(ListNode *head) 9 { 10 if (head == nul

【模板小程序】链表排序(qsort/insert_sort/merge_sort)

前言 本文章整理了链表排序的三种方法,分别是快速排序.插入排序.归并排序.为适应不同用途,先给出常用的int版本,再在此基础上抽象出类模板. 目录 一.针对整数的版本(常用) 文中链表定义 链表相关操作 三种排序方法 完整测试程序 二.模板版本(适用性广泛) 文中链表定义 链表相关操作 三种排序方法 完整测试程序 总结 参考文章 一.针对整数的版本(常用) 文中链表定义: 1 //definition for singly-linked list. 2 struct ListNode 3 { 4

HashMap源码解析(JDK1.8)

1 package java.util; 2 3 import sun.misc.SharedSecrets; 4 5 import java.io.IOException; 6 import java.io.InvalidObjectException; 7 import java.io.Serializable; 8 import java.lang.reflect.ParameterizedType; 9 import java.lang.reflect.Type; 10 import j

hashmap,解析

1 package java.util; 2 3 import sun.misc.SharedSecrets; 4 5 import java.io.IOException; 6 import java.io.InvalidObjectException; 7 import java.io.Serializable; 8 import java.lang.reflect.ParameterizedType; 9 import java.lang.reflect.Type; 10 import j

Leetcode文章整理

LeetCode的题目种类比较多,感觉应该将自己联系过的题目进行分类,这个就是根据自己做过的题目进行划分,并做一定的总结,会持续更新 Sort: Two Pointer: 单链表: Reorder List将l1->l2...->ln转化为l1->ln->l2->ln-1.. 这里用的很直接的方法就是找到链表的中点,然后将链表分为两部分,后半截翻转后两个链表进行融合.我在想,如果能之间把后面半截放入vector当中,就简单很多,但是就是牺牲了空间,不知道有没有更好的办法. I

[译]Memory Reordering Caught in the Act

原文:http://preshing.com/20120515/memory-reordering-caught-in-the-act/ 编写lock-free的C/C++程序时,在保证memory ordering正确性上要非常小心,否则,奇怪的事就来了. Intel在<x86/64 Architecture Specification>Volume 3, §8.2.3一节中列出了一些可能发生的“奇怪的事”. 来看一个小例子:X,Y两个变量均被初始化为0, 编写如下汇编代码,由两个处理器(p

HashMap 扩容分析

使用HashMap时我们需要注意一下几点问题: 1.HashMap是常用的Java集合之一,是基于哈希表的Map接口的实现.与HashTable主要区别为不支持同步和允许null作为key和value.  2.HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致.  3.如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap.  4.在JDK1

JAVA面试整理之——JAVA基础

1.     HashMap的源码,实现原理,JDK8中对HashMap做了怎样的优化. 在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.HashMap由链表+数组组成,他的底层结构是一个数组,而数组的元素是一个单向链表.但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低.而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,