1.用栈
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
Stack<ListNode> sta = new Stack<>();
while(head!=null){
sta.push(head);
head= head.next;
}
if(sta.empty()){
return null;
}
ListNode node = sta.pop();
ListNode newhead = node;
while(!sta.empty()){
ListNode tmp = sta.pop();
node.next = tmp;
node = node.next;
}
node.next = null;
return newhead;
}
}
2. 用双指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head, pre = null;
while(cur!=null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
链表内指定区间反转
emmmmm很多种情况没考虑,最后改了一个多小时才通过…
一开始考虑的最通用的情况是反转前有数字,并且至少有3个节点,因为是用上面的双指针的方法。
后来除了只有一个元素和只要反转一个的特殊情况之外,还有另一种情况:从第一位开始反转,所以设置头节点
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
ListNode pre = new ListNode(-1);
ListNode res = pre;
pre.next = head;
//将pre移动m-1步
int count = m-1;
while(count!=0){
pre = pre.next;
count --;
}
ListNode left = pre.next;
ListNode right = left;
//将right从left开始 移动n-m步
count = n-m;
while(count!=0){
right = right.next;
count--;
}
ListNode next = right.next;
//切断右边,后面反转才好判断
right.next = null;
ListNode pre2 = left;
ListNode cur = left.next;
while(cur!=null){
ListNode tmp = cur.next;
cur.next = pre2;
pre2 = cur;
cur = tmp;
}
//首尾
left.next = next;
pre.next = right;
return res.next;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
if(head.next==null || m==n) return head;
int i = 1;
ListNode prehead = new ListNode(0);
prehead.next = head;
ListNode newhead = head;
while(i<m-1){
prehead=prehead.next;
head = head.next;
i++;
}
ListNode l1 = null;
ListNode pre = null;
if(m==1){ //如果是从头反转就设置空头节点
l1 = prehead;
pre = prehead.next;
i++;
}
else{
l1 = head;
pre = head.next;
i = i + 2;
}
ListNode l2 = pre;
ListNode cur = pre.next;
while(i < n+1){//双指针
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
i++;
}
l2.next = cur;
l1.next = pre;
if(m==1) return prehead.next;
else return newhead;
}
}
下面是我第一次自己写
用栈反而时间更短了
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
Stack<ListNode> stack = new Stack<>();
ListNode newhead = head;
ListNode prehead = new ListNode(0);
prehead.next = head;
ListNode newprehead = prehead;
int i = 1;
while(i < m){
prehead= prehead.next;
head = head.next;
i++;
}
while(i<=n){
stack.push(head);
head = head.next;
i++;
}
while(!stack.empty()){
prehead.next = stack.pop();
prehead=prehead.next;
}
prehead.next = head;
return newprehead.next;
}
}