leetcode 150道题 计划花两个月时候刷完,今天(第二十二天)完成了4道(50-53)150:
50.(141. 环形链表)题目描述:
bash
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
第一版(这个是经典的题目,快慢指针就可以,如果有环他们肯定会相遇,没环一定会到 null )
java
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode low=head;
ListNode fast=head;
while(fast!=null&&low!=null){
low=low.next;
if(fast.next==null){
return false;
}
fast=fast.next.next;
if(low==fast){
return true;
}
}
return false;
}
}
第二版(我总感觉我对这个起始的指针处理不好,就看了一下解题,他是反着去判断了,也可以学习一下)
java
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null){
return false;
}
ListNode low=head;
ListNode fast=head.next;
while(low!=fast){
if(fast==null||fast.next==null){
return false;
}
fast=fast.next.next;
low=low.next;
}
return true;
}
}
51.(2. 两数相加)题目描述:
bash
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
第一版(这个题我第一反应以为他第一个指针是最大位数。。看了好久才读懂了题目。。但是这个题目处理的应该是一个模板,就是 3个while 的模板。。一般就是处理长度不一样的情况下我感觉都是3个while。。)
java
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode res=new ListNode(0);
ListNode resTemp=res;
int add=0;
while(l1!=null&&l2!=null){
int num=l1.val+l2.val+add;
add=num/10;
num%=10;
resTemp.next=new ListNode(num);
resTemp=resTemp.next;
l1=l1.next;
l2=l2.next;
}
while(l1!=null){
int num=l1.val+add;
add=num/10;
num%=10;
resTemp.next=new ListNode(num);
resTemp=resTemp.next;
l1=l1.next;
}
while(l2!=null){
int num=l2.val+add;
add=num/10;
num%=10;
resTemp.next=new ListNode(num);
resTemp=resTemp.next;
l2=l2.next;
}
if(add!=0){
resTemp.next=new ListNode(add);
resTemp=resTemp.next;
}
return res.next;
}
}
52.(21. 合并两个有序链表)题目描述:
bash
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
第一版(这个也是我上面说的长度不一样要一起处理的 3个while模板,只不过这个是链表,你只需要指定了头后面也会跟着这个头,所以这块就是 一个 while 两个 if)
java
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode res=new ListNode(0);
ListNode resTemp=res;
while(list1!=null&&list2!=null){
if(list1.val<list2.val){
resTemp.next=new ListNode(list1.val);
list1=list1.next;
}else{
resTemp.next=new ListNode(list2.val);
list2=list2.next;
}
resTemp=resTemp.next;
}
if(list1!=null){
resTemp.next=list1;
}
if(list2!=null){
resTemp.next=list2;
}
return res.next;
}
}
53.(138. 随机链表的复制) 题目描述:
bash
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。
返回复制链表的头节点。
用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
你的代码 只 接受原链表的头节点 head 作为传入参数。
第一版(这个题比较长,意思就是每个节点都要新建,我第一次写了好久,但是写出来还是一坨。。)
java
class Solution {
public Node copyRandomList(Node head) {
Node res=new Node(0);
Node resTemp=res;
Node headTemp=head;
Map<Node,Integer> nodeMap=new HashMap();
int index=0;
while(headTemp!=null){
resTemp.next=new Node(headTemp.val);
nodeMap.put(headTemp,index++);
headTemp=headTemp.next;
resTemp=resTemp.next;
}
Map<Integer,Integer> indexMap=new HashMap();
for (Map.Entry<Node, Integer> entry : nodeMap.entrySet()) {
if(entry.getKey().random==null){
indexMap.put(entry.getValue(),-1);
}
else
indexMap.put(entry.getValue(),nodeMap.get(entry.getKey().random));
}
// 复制 random 开始
resTemp=res.next;
Node temp=res.next;
index=0;
while(resTemp!=null){
temp=res.next;
if(indexMap.get(index)!=-1){
for(int i=0;i<indexMap.get(index);i++){
temp=temp.next;
}
resTemp.random=temp;
}
index++;
resTemp=resTemp.next;
}
return res.next;
}
}
第二版(看了解题,真的这个思想很好,把每个节点单独出来,一个一个来赋值他的 next和 random)
java
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;
}
Map<Node, Node> nodeMap = new HashMap<Node, Node>();
Node headTemp=head;
while(headTemp!=null){
nodeMap.put(headTemp,new Node(headTemp.val));
headTemp=headTemp.next;
}
headTemp=head;
while(headTemp!=null){
Node nodeNew=nodeMap.get(headTemp);
if(headTemp.next!=null){
nodeNew.next=nodeMap.get(headTemp.next);
}
if(headTemp.random!=null){
nodeNew.random=nodeMap.get(headTemp.random);
}
headTemp=headTemp.next;
}
return nodeMap.get(head);
}
}
昨天又鸽了一天。。不知道为啥昨天啥都不想干。。昨天把yys也删了,超鬼王真的肝不动了。。
加油,第二十二天了,早日跳槽!!!