所谓ARTS: 每周至少做一个LeetCode的算法题;阅读并点评至少一篇英文技术文章;学习至少一个技术技巧;分享一篇有观点和思考的技术文章。(也就是Algorithm、Review、Tip、Share 简称ARTS)这是第七期打卡。
Algorithm LeetCode算法
合并连个有序链表
(https://leetcode.com/problems/merge-two-sorted-lists/)
题目描述:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:1->2->4, 1->3->4输出:1->1->2->3->4->42->4, 1->3->4
输出:1->1->2->3->4->4
这个题目一看到的时候,吓我一跳,这个给出的链表,对于链表这个结构不是很熟悉的我来说,简直是一脸懵逼。讲真,小编一开始,连一个链表怎么创建都不知道,更不用说来解答了。
怎么办,拿到题目,看也没看,就在文章先写上了,那就只能迎着头皮去做了呗。什么数据结构与算法啊,什么算法导论都搬出来看下,哈哈,或许这就是这个打卡的意义所在吧。
这也给我敲了一个警钟,业务逻辑代码写的怎么样,并不代表编程能力怎么样;有经验的程序员更看重的就是基础的能力吧。大佬也说过,很多程序员都在不停地对业务代码进行bug的修改,没有系统的对基础进行学习,这也是我们要来刷题的目的之一吧。好啦,小编最后这道题是借助了网络能力才解答出来的,并不是真正的解答了,惭愧惭愧。
给出了三个解决方案,前两个是递归,最后一个不是,大家可以细细品味。网上的方法很多,顺带学习了下链表,真的很受用噢。
public static ListNode mergeTwoLists1(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode head = (l1.val < l2.val) ? l1 : l2; ListNode nonhead = (l1.val < l2.val) ? l2 : l1; head.next = mergeTwoLists1(head.next, nonhead); return head;}public static 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; }}public static ListNode mergeTwoListsNew(ListNode l1,ListNode l2) { if (l1 == null) { return l2; } if (l2 == null) { return l1; } ListNode dummy = new ListNode(-1), cur = dummy; while (l1 != null && l2 != null) { System.out.println("l1.val = " + l1.val + " l2.val = " + l2.val); 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 dummy.next;}
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode head = (l1.val < l2.val) ? l1 : l2;
ListNode nonhead = (l1.val < l2.val) ? l2 : l1;
head.next = mergeTwoLists1(head.next, nonhead);
return head;
}
public static 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;
}
}
public static ListNode mergeTwoListsNew(ListNode l1,ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode dummy = new ListNode(-1), cur = dummy;
while (l1 != null && l2 != null) {
System.out.println("l1.val = " + l1.val + " l2.val = " + l2.val);
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 dummy.next;
}
Review 阅读并点评至少一篇英文文章
睡眠质量比任何编程语言任何软件开发方法论都要重要
(https://threadreaderapp.com/thread/1119709859979714560.html?utm_source=wanqu.co&utm_campaign=Wanqu+Daily&utm_medium=website)
不知道怎么的,这篇文章看的有点云里雾里,感觉像是技术文,又感觉不像,尴尬尴尬。
作者率先提出了观点之一就是“你的睡眠质量和压力水平远远超过你使用的语言或你遵循的做法。”看完这个懵逼了,但是文中还有地方说道,如果你们周做50个小时的工作,那么在8到10周之后,你每周的工作效率低于40hpw的人,哈哈,这个和之前说的996.icu很像啊,说明长时间工作,不仅不能提升工作效率,反而还会减少。
文末也提到,没有任何方法,工具,语言,几乎与我们自己的思想一样重要。如果你想写出好的代码,那就要保证自己的健康,没有其他的要求。每每看到科技板块里出现某某人猝死,都时刻提醒自己,要记得锻炼、记得锻炼、记得锻炼。重要的事情说三遍,身体是革命的本钱。
朋友们,你想当一名优秀的程序员吗?你想写好代码吗?你想快乐的工作吗?那请你行动起来,保证好的睡眠,保证健康的身体,那你所想的一切,都会来的。
Tip 一个技术技巧
继续分享《Java核心技术36讲》做的学习笔记,关于内存模型和Java在Docker中运行的情形。
因为自己的主业是Java和Android开发,但是还没到精的地步,所以这些知识对我来说确实是蛮好用的,虽然很多还不明白,但这和读书一样,先把书读薄,再把书读厚,知识的储备就来了,加油加油。
第29讲 | Java内存模型中的happen-before是什么
Java内存模型(Java Memory Model,JMM)
典型回答
它的具体表现形式 ,包括但远不止是我们直觉中的synchronized、volatile、lock操作顺序等方面,例如:
volatile只保证可见性
第30讲 | Java程序运行在Docker等容器环境有哪些新问题?
典型回答
考点分析
有基础的话,可以从操作系统、容器原理、JVM内部机制,软件开发实践等角度,展示系统性分析新问题、新场景的能力。毕竟,变化才是世界永远的主题,能够在新变化中找出共性与关键,是优秀工程师的必备能力
知识扩展
Docker之类容器和向虚拟机非常相似,例如它有自己的shell,能独立安装软件包,运行时与其他容器互不干扰。但是,如果深入分析你会发现,Docker并不是一种完全的虚拟化技术,而更是一种轻量级的隔离技术
Share 一篇有观点和思考的技术文章
继续设计模式的学习执行,更新到观察者模式。在上面说道,我学习Java输出了一篇学后感,和大家一起共勉。
公众号地址:
设计模式之装饰者模式(一)
爱生活,爱学习,爱感悟,爱挨踢