1. 反转链表(LeetCode206)
反转一个单链表
public ListNode reverseList(ListNode head) {
if(head == null) return null;
ListNode pre = null;
ListNode cur = head;
//指针反转
while(cur != null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
2. 反转链表II(Leetcode92)
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode res = new ListNode(-1);
res.next = head;
ListNode node = res;
//找到需要反转的上一个
for(int i = 1; i < m; ++i){
node = node.next;
}
//node.next就是反转的起点
ListNode cur = node.next;
ListNode pre = null;
//反转m到n
for(int i = m; i <= n; ++i){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
//将反转的起点的next指向cur
node.next.next = cur;
//需要反转的上一个节点的next指向反转后链表的头结点
node.next = pre;
return res.next;
}
}
3. 两两交换链表中的节点(LeetCode24)
1234 —> 2143
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null || head.next == null) return head;
//新的头节点
ListNode newHead = head.next;
//指向已反转的第一个指针
head.next = swapPairs(head.next.next);
//新的头结点下一个是原来的头结点
newHead.next = head;
//返回新的头结点
return newHead;
}
}
4.K个一组翻转链表(LeetCode25)
给你指定链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || head.next == null) return head;
ListNode tail = head;
for (int i = 0; i < k; i++) {
//剩余数量小于k的话,则不需要反转。
if (tail == null) {
return head;
}
tail = tail.next;
}
// 反转前 k 个元素
ListNode newHead = reverse(head, tail);
//下一轮的开始的地方就是tail
head.next = reverseKGroup(tail, k);
return newHead;
}
/*
左闭右开区间
*/
private ListNode reverse(ListNode head, ListNode tail) {
ListNode pre = null;
ListNode cur = head;
//指针反转
while (cur != tail) {
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}