Topic: Hard Mode
Question:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL
, m = 2 and n = 4,
return 1->4->3->2->5->NULL
.
Note:
Given m, n satisfy the following condition:
1 ? m ? n ? length of list.
方法:
使用三个指针,确切的说还有一个不动的指针。
三个指针怎么运行的请大家看视频,这里不写了,中间过程中有断裂的时候,下次循环补上,最后跳出循环,再用静态不懂的那个指针指向空或者规定的位置。
另一个方法是递归:老样子,确定base case,确定输入输出,知道过程如何运行,可解。
Code1:
//非递归的方法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
// Start typing your Java solution below
// DO NOT write main() function
ListNode p = new ListNode(Integer.MIN_VALUE);
p.next = head;
int index = 1;
while(index < m){
p = p.next;
index++;
}
ListNode c = p.next;
ListNode ne = c.next;
ListNode mark = c;
while(index < n){
p.next = ne;
ne = ne.next;
p.next.next = c;
c = p.next;
index++;
}
mark.next = ne;
if(p.val == Integer.MIN_VALUE) return p.next;
else return head;
}
}
Code2:
//递归解法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
// Start typing your Java solution below
// DO NOT write main() function
int index = 1;
ListNode p = new ListNode(Integer.MIN_VALUE);
p.next = head;
while(index < m){
index++;
p = p.next;
}
ListNode mark = p.next;
p.next = reverse(mark, p.next, index, n);
if(p.val == Integer.MIN_VALUE) return p.next;
else return head;
}
private ListNode reverse(ListNode mark, ListNode c, int start, int end){
if(start == end){
mark.next = c.next;
return c;
}
else{
ListNode n = c.next;
c.next = null;
ListNode x = reverse(mark, n, start+1, end);
n.next = c;
return x;
}
}
}
Code3:
//将linkedlist逆序,递归法。
class Test{
public static void main(String[] args){
LinkedNode<Integer> head = new LinkedNode<Integer>(0);
LinkedNode<Integer> current = head;
int n = 10;
for(int i=1; i<n; i++){
LinkedNode<Integer> x = new LinkedNode<Integer>(i);
current.next = x;
current = current.next;
}
current = head;
for(int i=0; i<n; i++){
System.out.print(current.val + " ");
current = current.next;
}
System.out.println();
System.out.println("------------------------------------------");
LinkedNode<Integer> x = reverse(head);
current = x;
for(int i=0; i<n; i++){
System.out.print(current.val + " ");
current = current.next;
}
System.out.println();
System.out.println("------------------------------------------");
}
public static LinkedNode reverse(LinkedNode<Integer> c){
if(c == null) return null;
if(c.next == null) return c;
LinkedNode<Integer> n = c.next;
c.next = null;
LinkedNode<Integer> x = reverse(n);
n.next = c;
return x;
}
}
class LinkedNode<Item>{
Item val;
LinkedNode<Item> next;
public LinkedNode(Item item){
this.val = item;
next = null;
}
}
小结:
挺搞的一题,非递归法注意p节点位置不变以及c节点和n节点何时断开。
递归法注意在其中建立了一个看似没有联系的节点,却和下一层递归乃至最后的base case联系在一起。