【剑指offer】25. 合并两个排序的链表

118 阅读1分钟

题目描述

在这里插入图片描述 在这里插入图片描述

// 25. 合并两个排序的链表

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

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

题解

////////////////////////////// 遍历法 ////////////////////////////
// 力扣
// 执行用时:1 ms, 在所有 Java 提交中击败了98.60%的用户
// 内存消耗:38.3 MB, 在所有 Java 提交中击败了95.77%的用户
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
		if (l1 == null)
			return l2;
		if (l2 == null)
			return l1;
		ListNode head = new ListNode(-1);
		ListNode cur = head;  // 单结点
		
		// l1和l2这两个给定的指针作为遍历指针,在cur的前面遍历
		while (l1 != null && l2 != null) {
			// 谁小,cur.next会指向谁
			if (l1.val <= l2.val) {  // 如果l1值比l2值小
				cur.next = l1;  // cur.next指向l1
				l1 = l1.next;  // l1指针右移
			}
			else {
				cur.next = l2;
				l2 = l2.next;
			}
			// 上面的if else判据里,
			// 如果l1值比l2值小,之前cur.next会指向l1,此时cur右移到之前l1位置
			// 如果l2值比l1值小,之前cur.next会指向l2,此时cur右移到之前l2位置
			cur = cur.next;  
		}
		// 如果有链表没遍历完(该链表比另一个链表长)
		// cur.next指向该链表当前指针,直接连上长链表未遍历的尾巴
		if (l1 != null) {
			cur.next = l1;
		}
		if (l2 != null) {
			cur.next = l2;
		}
		return head.next;  // 返回head.next
    }
}

// 牛客
// 运行时间:16ms
// 占用内存:9948k
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        if (list1 == null)
            return list2;
        if (list2 == null)
            return list1;
        ListNode head = new ListNode(-1);
        ListNode cur = head;
        
        while (list1 != null && list2 != null) {
            if (list1.val <= list2.val) {
                cur.next = list1;
                list1 = list1.next;
            }
            else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        if (list1 != null) {
            cur.next = list1;
        }
        if (list2 != null) {
            cur.next = list2;
        }
        return head.next;
    }
}



// leetcode中的不同解法
// 运行时间:19ms 超过77.29%用Java提交的代码
// 占用内存:9916KB 超过70.27%用Java提交的代码
public class Solution {
    public ListNode Merge(ListNode l1,ListNode l2) {
        if (l1 == null)
            return l2;
        else if (l2 == null)
            return l1;

        ListNode temp = new ListNode(0);
        ListNode res;
        if (l1.val <= l2.val) res = l1;
        else res = l2;

        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                while (l1.next != null && l1.next.val <= l2.val) 
                    l1 = l1.next;
                temp = l1;
                l1 = l1.next;
                temp.next = l2;
            }
            else { // l1.val > l2.val
                while (l2.next != null && l1.val > l2.next.val) 
                    l2 = l2.next;
                temp = l2;
                l2 = l2.next;
                temp.next = l1;
            }
        }
		return res;
    }
}

遍历法图解(非leetcode中的解法)

在这里插入图片描述

///////////////////////////// 递归法 ////////////////////////
// 递归思路与遍历法是一样的,所以还是推荐遍历法,只是理解起来好看
// ,其资源消耗不可谓不小,因此该方法在牛客是无法通过的

// 力扣
// 执行用时:1 ms, 在所有 Java 提交中击败了98.60%的用户
// 内存消耗:38.8 MB, 在所有 Java 提交中击败了26.71%的用户
class Solution {
	public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
		if (l1 == null) {
			return l2;
		}
		if (l2 == null) {
			return l1;
		}
		ListNode head = new ListNode(-1);
		if (l1.val <= l2.val) {
			head = l1;
			head.next = mergeTwoLists(l1.next, l2);
		}
		else {
			head = l2;
			head.next = mergeTwoLists(l1, l2.next);
		}
		return head;
	}
}


在这里插入图片描述