赞
踩
leetcode:21
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路:
我们主要是通过定义两个节点,通过不断比较两个链表的节点值,然后让合并节点依次走过这些比较的节点值,从而达到有序;接下来图解说明比较好理解
1.我们设置两个节点,一个pre只要是头节点的前节点,用来保存头节点的位置,方便返回
2.进行遍历2个链表,此时链表A节点值为1 < B链表值为2,则合并节点成为节点值为1,如图
3.继续比较链表,此时链表B的节点值为2 < A链表的节点值3,则合并节点成为节点值为2,如图
4.继续比较,此时链表A的接地安置为3 < B链表的节点值为4,则合并节点为接地安置为3,如图
5.继续比较,此时链表B的接地安置为4 < A链表的节点值为5,则合并节点为接地安置为4,如图
6.继续比较,此时链表A的接地安置为5 < B链表的节点值为6,则合并节点为接地安置为5,如图
7.继续比较,此时链表B的接地安置为6 < B链表的节点值为7,则合并节点为接地安置为6,如图
8.继续比较,此时链表A的接地安置为7 < B链表的节点值为8,则合并节点为接地安置为7,如图
9.继续比较,此时A链表已经走完,而B链表还未走完,则合并节点为B链表的剩余节点处,即为8成为合并节点,此时pre所指向的路径就是合并的路径,返回pre节点
时间复杂度分析: 这里遍历两个链表,所以时间复杂度整体为O(n),两个链表的比较,也是O(n),所以整体时间复杂度为O(n)
空间复杂度:这里用了两个节点,但整体空间复杂度为O(1)
代码:
/** * 描述: 合并两个有序的链表 * * @author pengjie_yao * @date 2019/8/2 14:59 */ public class MergeTwoLists { /** * 节点 */ public static class ListNode { int val; ListNode next; public ListNode(int val) { this.val = val; } } /** * 合并两个有序链表 * * @param l1 * @param l2 * @return */ public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { // 1.判空处理 if (l1 == null && l2 != null) { return l2; } else if (l1 != null && l2 == null) { return l1; } else if (l1 == null && l2 == null) { return null; } // 2.设置一个头指针的前节点,用来保存头节点的位置,方便返回结果 ListNode preHead = new ListNode(-1); // 合并的链表指针,用来表示合并的节点处 ListNode mergeList = preHead; while (l1 != null && l2 != null) { // 3.如果链表1的节点小于链表2,则将合并的节点指向链表1的节点,并让合并节点成为该节点 if (l1.val < l2.val) { mergeList.next = l1; mergeList = l1; l1 = l1.next; } else { // 4.如果链表1的节点大于链表2的节点,则将合并的节点指向链表2的节点,并让合并节点成为该节点 mergeList.next = l2; mergeList = l2; l2 = l2.next; } } // 5.如果链表1为空,链表2不为空,则直接将合并节点指向链表2的节点 if (l1 == null && l2!=null) { mergeList.next = l2; } else if (l2 == null && l1!= null){ // 如果链表2为空,链表1不为空,则直接将合并节点指向链表1的节点 mergeList.next = l1; } return preHead.next; } public static void main(String[] args) { ListNode listNode = new ListNode(1); ListNode listNode1 = new ListNode(2); ListNode listNode2 = new ListNode(3); ListNode listNode3 = new ListNode(4); ListNode listNode4 = new ListNode(5); ListNode listNode5 = new ListNode(6); listNode.next = listNode2; listNode2.next = listNode4; listNode1.next = listNode3; listNode3.next = listNode5; ListNode resultNode = mergeTwoLists(listNode, listNode1); print(resultNode); } /** * 遍历链表 */ public static void print(ListNode node) { if (node == null) return; ListNode printNode = node; while (printNode != null) { System.out.print(printNode.val + " "); printNode = printNode.next; } System.out.println(); } }
其实上面的过程就是通过不断比较两个链表的值,过程基本都是重复的,所以用递归也可以实现;
/** * 递归方式 * @param l1 * @param l2 * @return */ public ListNode mergeTwoLists1(ListNode l1, ListNode l2) { if(l1 == null){ return l2; } if(l2 == null){ return l1; } if(l1.val <= l2.val){ l1.next = mergeTwoLists1(l1.next,l2); return l1; }else{ l2.next = mergeTwoLists1(l2.next,l1); return l2; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。