第一次被问反转链表是被字节,我没想出来。
后来在剑指offer上面看到了,我没做出来。
在leetcode和牛客上遇见,是那么的熟悉。
今天的每日一题还是思路不清晰。
我意识到,我是时候写点什么了。
希望下次遇到的时候思路清晰,一招毙命。
反转链表I是把整个链表都反转,相对来说容易一些,可以有迭代和递归两种方式。
迭代
public ListNode reverseList(ListNode head) {
ListNode prev =null;
ListNode curr = head;
while(curr!=null){
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
递归
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
public ListNode reverse(ListNode prev,ListNode curr){
if(curr == null){
return prev;
}
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
return reverse(prev,curr);
}
反转链表II相对来说就复杂了好多,需要反转的位置是第m个节点到第n个节点。也有两种思路:一种是继承了上面的方法,把m到n提出来反转完了再和其他部分拼接;另一种就是直接反转。
方法一
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode former = dummy;
for(int i=1;i<left;++i){
former = former.next;
}
ListNode prev = former;
ListNode curr = prev.next;
ListNode later = curr;
for(int i=left;i<=right;++i){
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
later.next = curr;
former.next = prev;
return dummy.next;
}
方法二
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode former = dummy;
for(int i=1;i<left;++i){
former = former.next;
}
head = former.next;
for(int i=left;i<right;++i){
ListNode next = head.next;
head.next = next.next;
next.next = former.next;
former.next = next;
}
return dummy.next;
}