目录
刷题日期:20:4133 星期三2021年3月31日
个人刷题记录,代码收集,来源皆为leetcode
经过多方讨论和请教,现在打算往Java方向发力
主要答题语言为Java
题目:
剑指 Offer 25. 合并两个排序的链表
难度简单103
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:
0 <= 链表长度 <= 1000
题目分析
没说链表里的数据一定是整数
又是链表题,连着三道了,集中训练啊,肯定得用指针,其次可以直接在其中一串上面进行操作,节省空间,合并链表需要注意后面的信息不能丢掉,因此可能还会需要临时指针,处理完毕后返回操作的那个链表即可。
初始解答:
尝试解答,参考了书:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//自己一开始没有想到递归的解法,看来链表是离不开递归了
//考虑特殊情况
if (l1 == null) return l2;
if (l2 == null) return l1;
//首先定义两个指针指向两个链表的头节点,和一个作为比较的节点
ListNode n1 = l1, n2 = l2, cur = null;
//其次判断需要从哪个开始,相等则随意
if (l1.val <= l2.val) {
//l1小则从l1开始
cur = l1;
cur.next = mergeTwoLists(l1.next,l2);
}
else {
//否则默认从l2开始
cur = l2;
cur.next = mergeTwoLists(l1,l2.next);
}
return cur;
}
}
执行结果: 通过
显示详情
执行用时:1 ms, 在所有 Java 提交中击败了99.67%的用户
内存消耗:38.7 MB, 在所有 Java 提交中击败了26.57%的用户
自己差在了没能看到链表就想到递归,不然这个思路并不难做出来。
尝试用迭代的方法实现,想复现K神的方法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dum = new ListNode(0), cur = dum; //伪头节点,和指针
while (l1.next != null && l2.next != null) {
if (l1.val < l2.val) {
dum.next = l1;
// dum.next = cur;
l1 = l1.next; //前进
}
else {
dum.next = l2;
// dum.next = cur;
l2 = l2.next;//前进
}
cur = cur.next; //不能缺,否则一直原地踏步
}
if (l1.next == null && l2.next != null) cur.next = l2;
if (l2.next == null && l1.next != null) cur.next = l1;
return dum.next;
}
}
分析不出来,老是输出两个数
输入 [1,2,4] [1,3,4]
输出 [2,4]
预期结果 [1,1,2,3,4,4]
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dum = new ListNode(0), cur = dum; //伪头节点,和指针
while (l1 != null && l2 != null) { //这里多了.next
if (l1.val < l2.val) {
cur.next = l1;
// dum.next = cur;
l1 = l1.next; //前进
}
else {
cur.next = l2;
// dum.next = cur;
l2 = l2.next;//前进
}
cur = cur.next; //不能缺,否则一直原地踏步
}
//判断时就不应该带这么多.next,本来就已经走到链尾了,再取就错了
// if (l1.next == null && l2.next != null) cur.next = l2;
// if (l2.next == null && l1.next != null) cur.next = l1;
//两句通俗实现,与下面那句一样的功能
if (l1 != null) cur.next = l1;
if (l2 != null) cur.next = l2;
//一句三元表达式或者条件判断表达式写法
// cur.next = l1 != null ? l1 : l2; //高深
return dum.next;
}
}
分析都在代码里了。
执行结果:通过
显示详情
执行用时:1 ms, 在所有 Java 提交中击败了99.67%的用户
内存消耗:38.6 MB, 在所有 Java 提交中击败了47.45%的用户
学习他人:
方法一:
mata川L5 2020-02-22
- 迭代
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(-1), pre = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
pre.next = l1;
pre = pre.next;
l1 = l1.next;
} else {
pre.next = l2;
pre = pre.next;
l2 = l2.next;
}
}
if (l1 != null) {
pre.next = l1;
}
if (l2 != null) {
pre.next = l2;
}
return dummyHead.next;
}
}
- 递归
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
方法二:
😶 (编辑过)2020-09-06
Java:
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// 遍历两个链表,比较大小合并。
// 申请一个伪头节点
ListNode dum = new ListNode(0);
ListNode cur = dum; // cur用来指向新插入的节点
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next; // cur指向刚插入进来的节点
}
// 若l1 == null,直接把l2后面插入进来。否则就是l2=null了。
// 跳出循环的条件是有一个为空了。
cur.next = l1 != null ? l1 : l2;
return dum.next; // dum是空节点,新链表的头节点是dum的后一个节点
}
}
方法三:
惯例K神,看过解释后更加明了了
作者:jyd
链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/mian-shi-ti-25-he-bing-liang-ge-pai-xu-de-lian-b-2/
来源:力扣(LeetCode)
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dum = new ListNode(0), cur = dum;
while(l1 != null && l2 != null) {
if(l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
}
else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 != null ? l1 : l2;
return dum.next;
}
}
总结
以上就是本题的内容和学习过程了,就两种解法,还是好好学习递归解法,迭代反而更复杂了,还得用到伪头节点,自己想的办法也没有尝试实现,之后再说。
欢迎讨论,共同进步。