算法通关村第二关——链表反转黄金挑战
- K 个一组翻转链表
- 方法一:自己写的
- 方法二:头插法
K 个一组翻转链表
25. K 个一组翻转链表
方法一:自己写的
我自己写的方式有点长,属于一点点一路路解决那种,其实用到的是穿针引线法,但是用的指针比较多
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode hummyNode = new ListNode(-1);
hummyNode.next = head;
// 定义一个变量,用于表示当前节点的位置
ListNode cur = hummyNode;
// 只要下一个节点不为空,就一直循环
// 为了解决两个问题:1. k == 链表节点数 2.链表节点就一个
while(cur.next != null){
// 定义三个变量,用于表示当前区间的左边节点、右边节点以及前一个节点
ListNode prev = cur;
ListNode left = prev.next;
ListNode right = cur;
// 找到需要交换的区间
int num = k;
while(right != null && num != 0){
right = right.next;
num--;
}
// 如果右区间为空,表示区间长度不足k,所以直接退出循环
if(right == null){
break;
}
// 否则,保留右区间的下一个节点,以便后续连接链表,有可能刚刚好结束和后面还有数
ListNode temp = null;
if(right.next != null){
temp = right.next;
right.next = null;
}
// 反转左右区间的链表,并将当前左区间的前驱节点连接到右区间
reverseList(prev.next);
prev.next = right;
left.next = temp;
// 移动当前节点到下一个需要反转的链表的前一个节点
cur = left;
}
// 返回反转后的链表
return hummyNode.next;
}
// 翻转链表
private 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;
}
}
方法二:头插法
这个方法就稍微简单理解一点,主要是记录需要翻转的次数
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode cur = head;
int len = 0;//先计算出链表的长度
while(cur != null) {
len++;
cur = cur.next;
}
int n = len/k;//计算出有几组
ListNode pre = dummyNode;
cur = head;
for(int i=0;i<n;i++) {
for(int j=0;j<k-1;j++) {
ListNode next = cur.next;
cur.next = cur.next.next;
next.next = pre.next;
pre.next = next;
}
pre = cur;
cur = cur.next;
}
return dummyNode.next;
}
}
over~~