剑指Offer之合并两个排序的链表

题目描述:

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
(hint: 请务必使用链表。)

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为两个整数n和m(0<=n<=1000, 0<=m<=1000):n代表将要输入的第一个链表的元素的个数,m代表将要输入的第二个链表的元素的个数。
下面一行包括n个数t(1<=t<=1000000):代表链表一中的元素。接下来一行包含m个元素,s(1<=t<=1000000)。

输出:

对应每个测试案例,
若有结果,输出相应的链表。否则,输出NULL。

样例输入:
5 2
1 3 5 7 9
2 4
0 0
样例输出:
1 2 3 4 5 7 9
NULL
/*********************************
*   日期:2013-11-23
*   作者:SJF0115
*   题号: 题目1519:合并两个排序的链表
*   来源:http://ac.jobdu.com/problem.php?pid=1519
*   结果:AC
*   来源:剑指Offer
*   总结:
**********************************/
#include<iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;

typedef struct ListNode{
    int value;
    struct ListNode* next;
}ListNode;

//打印链表
void OutPut(ListNode*head){
    if(head == NULL){
        printf("NULL\n");
    }
    else{
        ListNode *p;
        p = head->next;
        while(p != NULL){
            //如果是最一个
            if(p->next == NULL){
                printf("%d\n",p->value);
            }
            else{
                printf("%d ",p->value);
            }
            p = p->next;
        }
    }
}
//创建链表
ListNode* CreateList(ListNode *head,int n){
    ListNode *newNode,*p;
    p = head;
    for(int i = 0;i < n;i++){
        newNode = (ListNode*)malloc(sizeof(ListNode));
        scanf("%d",&newNode->value);
        newNode->next = NULL;
        p->next = newNode;
        p = newNode;
    }
    return head;
}
ListNode* Merge(ListNode*head1,ListNode*head2){
    //head1,head2带有头结点
    if(head1->next == NULL && head2->next == NULL){
        return NULL;
    }
    //只有第一个字符串,无需合并,直接输出
    else if(head2->next == NULL){
        return head1;
    }
    //只有第二个字符串,无需合并,直接输出
    else if(head1->next == NULL){
        return head2;
    }
    //合并
    else{
        ListNode *p1,*p2,*p3,*head;
        head = (ListNode*)malloc(sizeof(ListNode));
        head->next = NULL;
        p1 = head1->next;
        p2 = head2->next;
        p3 = head;
        while(p1 != NULL && p2 != NULL){
            if(p1->value < p2->value){
                p3->next = p1;
                p1 = p1->next;
            }
            else{
                p3->next = p2;
                p2 = p2->next;
            }
            p3 = p3->next;
        }
        //head1没有遍历完
        while(p1 != NULL){
            p3->next = p1;
            p1 = p1->next;
            p3 = p3->next;
        }
        //head2没有遍历完
        while(p2 != NULL){
            p3->next = p2;
            p2 = p2->next;
            p3 = p3->next;
        }
        return head;
    }
}
int main() {
    int i,n,m;
    while(scanf("%d %d",&n,&m) != EOF){
        ListNode *head1,*head2;
        head1 = (ListNode*)malloc(sizeof(ListNode));
        head2 = (ListNode*)malloc(sizeof(ListNode));
        head1->next = NULL;
        head2->next = NULL;
        //创建链表
        if(n != 0){
            head1 = CreateList(head1,n);
        }
        if(m != 0){
            head2 = CreateList(head2,m);
        }
        //合并排序
        head1 = Merge(head1,head2);
        //打印链表
        if(head1 == NULL){
            printf("NULL\n");
        }
        else{
            OutPut(head1);
        }
    }//while
    return 0;
}

【方法二】

【解析】

【代码】

/*********************************
*   日期:2013-11-23
*   作者:SJF0115
*   题号: 题目1519:合并两个排序的链表
*   来源:http://ac.jobdu.com/problem.php?pid=1519
*   结果:AC
*   来源:剑指Offer
*   总结:
**********************************/
#include<iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;

typedef struct ListNode{
    int value;
    struct ListNode* next;
}ListNode;

//打印链表
void OutPut(ListNode*head){
    if(head == NULL){
        printf("NULL\n");
    }
    else{
        ListNode *p;
        p = head;
        while(p != NULL){
            //如果是最一个
            if(p->next == NULL){
                printf("%d\n",p->value);
            }
            else{
                printf("%d ",p->value);
            }
            p = p->next;
        }
    }
}
//创建链表
ListNode* CreateList(ListNode *head,int n){
    ListNode *newNode,*p;
    p = head;
    for(int i = 0;i < n;i++){
        newNode = (ListNode*)malloc(sizeof(ListNode));
        scanf("%d",&newNode->value);
        newNode->next = NULL;
        p->next = newNode;
        p = newNode;
    }
    return head;
}
//递归
ListNode* Merge(ListNode*head1,ListNode*head2){
    if(head1 == NULL && head2 == NULL){
        return NULL;
    }
    else if(head2 == NULL){
        return head1;
    }
    else if(head1 == NULL){
        return head2;
    }
    //合并
    ListNode *head = NULL;
    if(head1->value < head2->value){
        head = head1;
        head->next = Merge(head1->next,head2);
    }
    else{
        head = head2;
        head->next = Merge(head1,head2->next);
    }
    return head;
}
int main() {
    int i,n,m;
    while(scanf("%d %d",&n,&m) != EOF){
        ListNode *head1,*head2;
        head1 = (ListNode*)malloc(sizeof(ListNode));
        head2 = (ListNode*)malloc(sizeof(ListNode));
        head1->next = NULL;
        head2->next = NULL;
        //创建链表
        if(n != 0){
            head1 = CreateList(head1,n);
        }
        if(m != 0){
            head2 = CreateList(head2,m);
        }
        //合并排序
        head1 = Merge(head1->next,head2->next);
        //打印链表
        if(head1 == NULL){
            printf("NULL\n");
        }
        else{
            OutPut(head1);
        }
    }//while
    return 0;
}
时间: 2024-10-21 11:48:19

剑指Offer之合并两个排序的链表的相关文章

《剑指offer》-合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. class Solution{ public: ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ ListNode* result = NULL; ListNode* current = NULL; if (pHead1 == NULL){ return pHead2; } if (pHead2 == NULL){ return pHead1; }

剑指offer系列之十五:合并两个排序的链表

题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 这道题我的第一思路这样的:可以先遍历这两个排序的链表,把遍历的结果存放在一个集合中,然后调用库函数Arrays.sort方法完成排序,之后,根据这些排好序的结果重新创建一个链表,即为合并之后但仍然排序的链表.但是这种思路需要额外的List和创建链表的空间开销,而且时间复杂度最快也是O(nlogn).所以不是很理想.第二种思路是这样的:因为两个链表都是排序的,所以可以先比较两个链表的头结点,这样

[剑指Offer]9.用两个栈实现队列

题目 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路 用栈来模拟队列.我们首先插入一个元素a到stack1中,再压入两个元素bc,此时栈中有元素abc,其中c位于栈顶,而stack2仍然为空.我们试着删除一个元素.按照队列先进先出的原则,我们应该先删除元素a.元素a存放在stack1中且不在栈顶,因此不能直接删除.注意到stack2还未使用,我们把stack1中的元素逐个弹出并压入stack2中,stack2中的元素是cba,栈顶元素是a,我们现在可以

剑指offer系列之十四:反转链表

题目描述 输入一个链表,反转链表后,输出链表的所有元素. 思路如下:在遍历链表上的每个节点的时候,就修改其指针,当遍历到最后一个结点的时候,整个链表就反转完成了.所以需要创建三个变量:一个是当前遍历的结点,一个是遍历结点的前一个结点,还有一个是当前遍历结点的下一个结点.基于这种思路可以写出如下的实现代码(已被牛客AC): package com.rhwayfun.offer; public class ReverseLinkedList { public static class ListNod

[剑指Offer] 第3章课后题详解

[剑指Offer] 第3章课后题详解 目录 剑指Offer 第3章课后题详解 目录 大数加法 分析 解法 优化 链表的中间节点 分析 解法 环形链表 分析 解法 反转链表 分析 解法 大数加法 本题为<剑指Offer>"面试题12:打印1到最大的n位数"一节中的"相关题目". 定义一个函数,在该函数中可以实现任意两个整数的加法. 分析 由于没有限定输入两个数的大小范围,所以需要把它当做大数问题来处理.大数无法用int,long甚至long long类型来

剑指offer学习笔记1

C++的标准不允许复制构造函数传值参数.A(const A& other){},如果是传值参数,把形参复制到实参会调用复制构造函数,就会形成无休止的递归调用从而导致栈溢出. 赋值运算符函数 class CMyString { public: CMyString(char *pData = NULL); CMyString(const CMyString& str); ~CMyString(); CMyString& operator=(const CMyString& ot

剑指offer之和为定值的两个数

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出"-1 -1" 样例输入: 6 15 1 2 4 7 11 15 样例输出:

剑指Offer之和为S的两个数字

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出"-1 -1" 样例输入: 6 15 1 2 4 7 11 15 样例输出:

《剑指offer》写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

弱菜刷题还是刷中文题好了,没必要和英文过不去,现在的重点是基本代码能力的恢复. [题目] 剑指offer 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 直觉想到用二进制的位运算.最后写出来是一个迭代的过程. 每次迭代先计算x和y的和但不处理进位,那么相当于做异或,得到res1 然后处理进位问题,相当于计算与运算,得到res2 那么res2左移1位,再加到res1上,则整个运算的最终结果转化为res1+(res2<<1) 因为res2做左移,总会减小到