线性时间将两个有序链表合成一个有序链表(constant additional space)

description:

given two sorted singly list, merge them into one using constant additional
space

algorithm:

we will reference the two linked list as list1 and list2 for convenience,

since list1 is sorted,just find the right position for each element in
list2,

detailed comments are added to the following 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

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

#include<iostream>

#include<cstdio>

#include<string.h>

#include<string>

#include<cstring>

#include<algorithm>

using
namespace std;

class
Node{

public:

    int
value;

    Node* Next;

    Node(int
v_ = 0, Node* Next_ = NULL):value(v_),Next(Next_){}

};

/*Node* Merge2(Node* head1, Node* head2)

{

    Node* res,*ret;

    if(head1 == NULL) return head2;

    if(head2 == NULL) return head1;

    Node* p = head1;

    Node* q = head2;

    

    if(p->value < q->value)

    {

        res = p;

        p = p->Next;

    }

    else

    {

        res = q;

        q = q->Next;

    }

    ret = res;

    while(p && q)

    {

        if(p->value < q->value)

        {

            res->Next = p;

            res = p;

            p = p->Next;

        }

        else

        {

            res->Next = q;

            res = q;

            q = q->Next;

        }

    }

    while(p)

    {

             res->Next = p;

                  res = p;

        p = p->Next;

    }

    while(q)

    {

        res->Next = q;

        res = q;

        q = q->Next;

    }

    return ret;

}*/

Node* Merge2(Node*p1,Node*p2){

    if(p1 == NULL)

        return
p2;

    if(p2 == NULL)

        return
p1;

    Node *tmpp1 = p1,*tmpp2 = p2;

    Node*head;

    bool
first = true;

    /*core optimization: if tmpp2 find its place in list1, then tmpp2->next must be after its position,so both list1 and list2

      are enumerated only once, which implements linear algorithm*/

    while(tmpp1 != NULL && tmpp2 != NULL){

        Node* tmpformer = NULL;

        while(tmpp1 != NULL && tmpp2->value > tmpp1->value){

            tmpformer = tmpp1;

            tmpp1 = tmpp1->Next;

        }

        if(tmpp1 == NULL){

            tmpformer->Next = tmpp2;

            if(first){

                first = false;

                head = p1;

            }

            break;

        }

        //tmpp2的value值比tmpp1的value值小但是比tmpformer的value值大

        Node* tmprecordp2 = tmpp2->Next;

        tmpp2->Next = tmpp1;

        if(tmpformer != NULL){

            tmpformer->Next = tmpp2;

            if(first){

                first = false;

                head = p1;

            }

        }

        else{

            if(first){

                first = false;

                head = p2;

            }

        }

        tmpp2 = tmprecordp2;

    }

    return
head;

}

int
main(){

    Node* p1[10], *p2[10];

    memset(p1,0,sizeof(p1));

    memset(p2,0,sizeof(p2));

    int
a[25] = {1,3,6,7,8,9,56,67,211,763,2,4,5,10,11,12,13,300,500,800};

    /*initalization*/

    for(int
i = 0; i < 10; ++i){

        p1[i] = new
Node(a[i]);

    }

    for(int
i = 0; i < 10; ++i){

        p2[i] = new
Node(a[10+i]);

    }

    Node* pp1,*pp2;

    for(int
i = 0; i < 9; ++i){

    //  cout << &(p1[i]->Next) << endl;

        p1[i]->Next = p1[i+1];

    }

    for(int
i = 0; i < 9; ++i){

        p2[i]->Next = p2[i+1];

    }

        pp1 = p1[0];

    while(pp1 != NULL){

        cout << pp1->value << ‘\t‘;

        pp1 = pp1->Next;

    }

    cout << endl;

    pp2 = p2[0];

    while(pp2 != NULL){

        cout << pp2->value << ‘\t‘;

        pp2 = pp2->Next;

    }

    cout << endl;

    /*initialization end*/

    Node* res = Merge2(p1[0],p2[0]);

    while(res!=NULL){

        cout << res->value << endl;

        res = res->Next;

    }

    for(int
i = 0; i < 10; ++i){

        delete
p1[i];

    }

    for(int
i = 0; i < 10; ++i){

        delete
p2[i];

    }

    return
0;

}

key points:

1.pay special attention to keep head pointer, which is easily lost,

my solution is to set a flag bool variance, which is linear complexity
but somewhat inefficient

perhaps it has potential to improve

2.avoid misorder of pointer

3.special condition: if (p1 == NULL) return p2;

if(p2 == NULL ) return p1;

4.when search for the postion for a certain element in list1, note that it
might be above any element in list1 so tmpp1 might reach its end(value equals
NULL) during search

线性时间将两个有序链表合成一个有序链表(constant additional space),码迷,mamicode.com

时间: 2024-10-21 00:24:14

线性时间将两个有序链表合成一个有序链表(constant additional space)的相关文章

两个有序链表合成一个有序链表

RT.... 无聊帮朋友撸个 C++ 作业.. = = 1 /* 2 无聊帮朋友撸个作业...... \ = v = / 3 4 两个有序链表合成为一个有序链表. 5 要求: 6 1. 每个链表元素里的值不超过int范围. 7 2. 两个链表要求为升序(从小到大). 8 9 10 2016.1.5 author : 加德满都的猫会爬树 11 12 */ 13 14 #include <iostream> 15 using namespace std; 16 const int MAX = 10

【LeetCode】两个有序数组合成一个有序数组(NEW)

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n.你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素.示例: 输入:nums1 = [1,2,3,0,0,0], m = 3nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6] 解法1: 之前如果不考虑合并,空间上新增一个数组

27、输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 思路:同归并算法 本题: 1 public class Solution { 2 public ListNode Merge(ListNode list1, ListNode list2) { 3 ListNode head; 4 if (list1 == null) { 5 return list2; 6 } 7 if (list2 == null) { 8 return list1; 9 } 10

两个有序数组组成一个有序的数组

package com.hzins.suanfa; import java.util.Arrays; /** * * 两个有序数组组成一个有序的数组 * 整个循环层数为1 * 以其中一个数组做循环,注意另外一个的index是否溢出以及另外一个是否没有遍历完成 * * @author Administrator * */ public class Demo2 { /** * * 1,3,5,7 * 2,4,6,8 * @param a * @param b */ public static voi

将两个无序链表合成一个链表

对于链表,可以先将两个链表排序,然后再将其枚举合成一个链表. 或者是先将一个链表接到另一个链表的尾部,然后将总链表排序. 1 #include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <malloc.h> 6 using namespace std; 7 struct Node{ 8 int date; 9

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

新增一个链表,然后分别采用2个指针指向这两个链表,每次比较链表的值,将较小的那一个存入新链表中.需要主要的是对空链表进行处理,主要还是考察代码的鲁棒性.总共2个链表,数组分别是1,3,5,7,和2, 4, 6,8 采用java进行实现. package com.test.algorithm; class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } public class Me

Submission Details [leetcode] ---- inplace 线性时间 的两种思路

两种思路都利用了输入的数组A,若A中存在i,则给A[i]作为标记. 因为A中的n个元素存在>n和<=0的,所以第一个缺失的正整数一定在[1-n+1]之间. 第一种思路是将标记设为一个特定的数.因为改变数值会影响该位置原来存的值,所以需要在一个循环里依次处理所有"原来的值". 例如数组为{2,3,4,1}.对第一个数2,我们将位置(2-1)=1标记为-MAX_INT,数组变为{2,-MAX_INT,4,1},丢失了3,所以应记录下数组原来的值,并继续将位置(3-1)=2标记为

面试题:2个有序数组变为一个有序数组

剑指offer  面试题5的相关题目 2019.3 纽迈科技曾问过这个问题. 思路1 :直接将两个数组合并在一起,然后排序,这时候需要考虑是快排还是啥的排序算法,压根没考虑数组的有序性! 思路2:从头开始,分别比较对应数组,小的留下,这里需要一个问题,若2个数组的len不一样,这时候你要将剩下的那个较长的元素直接存储. 这里学习了.append()   .extend()  和 + 的用法,重新整理: 原文地址:https://www.cnblogs.com/ivyharding/p/11212

链表合成

题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 方法一:递归 public class MergeList { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ListNode list1 = new ListNode(); ListNode list2 = new ListNode(); Lis