题目:
将一个链表m位置到n位置之间的区间反转,要求使用原地算法,并且在一次扫描之内完成反转。
例如:
给出的链表为1->2->3->4->5->NULL, m = 2 ,n = 4,
返回1->4->3->2->5->NULL.
注意:
给出的m,n满足以下条件:
1 ≤ m ≤ n ≤ 链表长度
思路:
- 找到链表需要翻转的部分(起点和终点)
- 进行翻转
代码:
package com.company;
public class TestNo30 {
static class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
public String toString(){
if(this.next == null){
return String.valueOf(this.val);
}
return this.val + "->" + this.next.toString();
}
}
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);
System.out.println(head);
System.out.println(new TestNo30().reverseBetween(head,2,4));
}
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head == null || head.next == null){
return head;
}
ListNode node = new ListNode(0);
node.next = head;
ListNode prev = node;
ListNode begin = head;
//找到翻转的起点
while (m>1){
prev = begin;
begin = begin.next;
m--;
}
ListNode end = head;
//转到翻转的终点
while (n>1){
end = end.next;
n--;
}
//对找到的部分进行翻转,传进去的第一个是需要翻转部分起点的前一个,
//和终点部分的后一个
reverse(prev,end.next);
return node.next;
}
//对规定部分进行翻转
private ListNode reverse(ListNode node,ListNode afterend){
ListNode prev = node;
ListNode cur = node.next;
ListNode nextNode = cur.next;
while (nextNode!= afterend){
cur.next = nextNode.next;
nextNode.next = prev.next;
prev.next = nextNode;
nextNode= cur.next;
}
return node.next;
}
}