leetcode 150道题 计划花两个月时候刷完,今天(第二十三天)完成了1道(54)150:
54.(92. 反转链表 II) 题目描述:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
第一版(还是照着老思路去写了,把每个节点复制了一边。。但好像解题写的是不用复制就可以的,所以今天把链表这块很好看了一下)
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
int count=0;
ListNode res=new ListNode(0);
ListNode resTemp=res;
ListNode leftTemp=res;
while(head!=null){
ListNode temp=new ListNode(head.val);
count++;
if(count==left)
leftTemp=resTemp;
if(count>left&&count<=right){
temp.next=leftTemp.next;
leftTemp.next=temp;
}else{
resTemp.next=temp;
resTemp=resTemp.next;
}
head=head.next;
}
return res.next;
}
}
第二版(再看第二版之前我去刷了一遍,简单的反转链表学习了一下不用每次都复制的反转法。。)
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode currNode = dummyHead;
for(int i=0;i<left-1;i++){
currNode=currNode.next;
}
ListNode rightNode=currNode;
// 再走到right 就是要反转的结尾
for(int i=0;i<right-left+1;i++){
rightNode=rightNode.next;
}
// 取出 再截断 当前链表
// 这个是 中间链表的
ListNode leftNode=currNode.next;
// 这个是 后面 一段的头(开始 中间<要反转的链表> 后面剩余的链表头)
ListNode endNodeHead= rightNode.next;
rightNode.next=null;
// 反转
reverseNodes(leftNode);
// 拼接回来 开始+中间<要反转的链表>+后面剩余的链表
currNode.next=rightNode;
leftNode.next=endNodeHead;
return dummyHead.next;
}
public void reverseNodes(ListNode leftNode){
ListNode preNode=null;
while(leftNode!=null){
ListNode temp= leftNode.next;
leftNode.next=preNode;
preNode=leftNode;
leftNode=temp;
}
}
}
额外题(206. 反转链表)题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
第一版(但是没搞懂,解题里面把head赋值了一个变量,遍历都用变量去做的,这是为啥。。)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode preNode=null;
while(head!=null){
ListNode next= head.next;
head.next = preNode;
preNode = head;
head = next;
}
return preNode;
}
}
今天看了一下解题感觉自己对链表这块确实还朦朦胧胧,但是我总感觉他这样写和我每次取出来val 值再去新建差不多。。但是我的确实是新建效率肯定没人家这好。。再看看吧。。
第二十三天,为跳个好槽加油!!!