剑指offer 25:合并两个有序链表

题目描述:

输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。

数据范围: 0 ≤ n ≤ 10000≤n≤1000,-1000 ≤ 节点值 ≤ 1000−1000

要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:

 或输入{-1,2,4},{1,3,4}时,合并后的链表为{-1,1,2,3,4,4},所以对应的输出为{-1,1,2,3,4,4},转换过程如下图所示:

 示例1:

输入:{1,3,5},{2,4,6}

返回值:{1,2,3,4,5,6}

示例2:

输入:{},{}

返回值:{}

示例3:

输入:{-1,2,4},{1,3,4}

返回值:{-1,1,2,3,4,4}

解法一:双指针

首先定义一个新链表,定义temp指向新链表的头节点。之后,利用两个指针,分别指向 list1 和 list2,然后逐次比较 list1 和 list2值的大小:

  • 如果 list1.val 小于 list2.val,则 list1 指向的节点连接到 temp 的 next 指针,然后 list1 指向下一个节点值。
  • 如果 list1.val 大于等于 list2.val,则 list2 指向的节点连接到 temp 的 next 指针,然后 list2 指向下一个节点值。

 代码如下:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        //如果list1为空,直接返回list2
        if(list1 == null){
            return list2;
        }
        //如果list2空,直接返回list1
        if(list2 == null){
            return list1;
        }
        //结果链表
        ListNode result = new ListNode(0);
        //指向结果链表的当前节点
        ListNode temp = result;
        //循环结束条件:list1和list2中有一个遍历结束
        while(list1 != null && list2 != null){
            //如果list1的值小于list2的值,temp.next=list1,list1向后遍历,反之,temp.next=list2,list2向后遍历
            if(list1.val < list2.val){
                temp.next = list1;
                list1 = list1.next;
            }else{
                temp.next = list2;
                list2 = list2.next;
            }
            temp = temp.next;
        }
        //如果list1没遍历完,直接让temp.next等于list1
        if(list1 != null){
            temp.next = list1;
        }
        //如果list2没遍历完,直接让temp.next等于list2
        if(list2!= null){
            temp.next = list2;
        }
        //返回结果
        return result.next;
    }
}

解法二:递归

递归算法也可以解决这个问题,需要明确的是:递归结束的条件是什么?即:链表为空。在递归的过程中,其范围是逐步缩小的。

当 list1.val 小于 list2.val 时,list1 就是新序列的开始位置,后面的部分就是 list1.next 和 list2 的重新排序的结果。

同理,当 list1.val 大于等于 list2.val 时,list2 就是新序列的开始位置,后面的部分就是 list2.next 和 list2 的重新排序的结果。

代码如下:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        //如果list1为空,直接返回list2
        if(list1 == null){
            return list2;
        }
        //如果list2空,直接返回list1
        if(list2 == null){
            return list1;
        }
       if(list1.val < list2.val){
           list1.next = Merge(list1.next, list2);
           return list1;
       }else{
           list2.next = Merge(list1, list2.next);
           return list2;
       }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/121027132