合并列表算法(迭代+递归)

合并两个列表算法(java实现)

题目

将两个升序链表合并成一个新的升序链表。
输入:1->2->4,1->3->4
输出:1->1->2->3->4->4

分析

1.迭代实现

1.建立一个临时结点方便处理
2.不断比较L1,L2的值,哪个小就放到临时结点的后面
3.其中一个为空后,将不空的直接放在最后

过程

List1:1->2->4
List2:1->3->4
最终列表:临时结点->
策略:谁小往临时节点后加谁,一样的话附加List1的元素

比较:List1的第一个元素1 和 List2中的第一个元素1
结果:相同
List1:2->4
List2:1->3->4
最终列表:临时结点->1

List1:2->4
List2:3->4
最终列表:临时结点->1->1

List1:4
List2:3->4
最终列表:临时结点->1->1->2

时间复杂度 O(N)
空间复杂度 O(1)

2.递归实现

假设方法mergeTwoList_2可以完成这个任务,mergeTwoList_2需要传入两个列表的列表头。假设传入了两个列表,直接比较这两个列表的第一个元素的大小,决定这个节点放置哪个元素,之后将剩余的排序任务交给mergeTwoList_2去完成;之后,还需要考虑一个问题,就是终止条件是什么,那自然是其中一个列表为空,直接将剩余的列表加入到最终列表中。

时间复杂度 O(N)
空间复杂度 O(N)
是不是感觉这么写有大病,性能没提升,反而浪费了空间,确实。。。但是这个方法的好处,就是代码量一般要少于其他方法,在有些题目中容易想到,说道性能,真的不咋的。

代码

工具类代码

节点代码
public class ListNode {
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val){
        this.val=val;
    }
    ListNode(int val,ListNode next){
        this.val=val;
        this.next=next;
    }
}
打印工具类代码
public class UtilListNode {

    public static void printNode(ListNode head) {
        if (head == null) {
            System.out.println("Empty!");
            return;
        }
        StringBuilder sb = new StringBuilder();
        while (head != null) {
            sb.append(head.val);
            if (head.next != null) {
                sb.append("-->");
            }
            head = head.next;
        }
        System.out.println(sb.toString());
    }
}

迭代法代码

public class mergeTwoList {

    public ListNode mergeTwoList(ListNode l1, ListNode l2) {
        ListNode p = new ListNode();
        ListNode head = p;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                p.next = l1;
                l1 = l1.next;
            } else {
                p.next = l2;
                l2 = l2.next;
            }
            p = p.next;
        }
        p.next = (l1 == null ? l2 : l1);
        return head.next;
    }

    public void test() {
        ListNode a1 = new ListNode(1);
        ListNode a2 = new ListNode(2);
        ListNode a3 = new ListNode(4);
        ListNode b1 = new ListNode(1);
        ListNode b2 = new ListNode(3);
        ListNode b3 = new ListNode(4);
        a1.next = a2;
        a2.next = a3;
        b1.next = b2;
        b2.next = b3;
        UtilListNode.printNode(a1);
        UtilListNode.printNode(b1);
        UtilListNode.printNode(mergeTwoList(a1, b1));
    }

    public static void main(String[] args) {
        mergeTwoList t=new mergeTwoList();
        t.test();
    }

}

递归法代码

public class mergeTwoList {
    public ListNode mergeTwoList_2(ListNode l1, ListNode l2) {
        if (l1 == null || l2 == null) {
            return l1 == null ? l2 : l1;
        }
        if (l1.val<=l2.val){
            l1.next=mergeTwoList_2(l1.next,l2);
            return l1;
        }else {
            l2.next=mergeTwoList_2(l1,l2.next);
            return l2;
        }
    }

    public void test() {
        ListNode a1 = new ListNode(1);
        ListNode a2 = new ListNode(2);
        ListNode a3 = new ListNode(4);
        ListNode b1 = new ListNode(1);
        ListNode b2 = new ListNode(3);
        ListNode b3 = new ListNode(4);
        a1.next = a2;
        a2.next = a3;
        b1.next = b2;
        b2.next = b3;
        UtilListNode.printNode(a1);
        UtilListNode.printNode(b1);
        UtilListNode.printNode(mergeTwoList_2(a1, b1));
    }

    public static void main(String[] args) {
        mergeTwoList t = new mergeTwoList();
        t.test();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值