标题对于给定的K(K>0),逆置链表中包含K个结点的块
例:输入:1 2 3 4 5 6 7 8 9 10 对于不同的K,输出为:
K = 2:2 1 4 3 6 5 8 7 10 9
K = 3:3 2 1 6 5 4 9 8 7 10
K = 4:4 3 2 1 8 7 6 5 9 10
算法:
1)检查链表当前剩余部分是否还有K+1个结点
a)如果有,获取当前链表剩余部分第K+1个结点的指针
b)若没有,则返回
2)逆置前面的K个结点
3)K个结点逆置之后,如果后面还有一个K块,则设置当前K块的最后一个结点的后继指针指向下一个K块的最后一个结点,若没有,则指向剩余部分的第一个结点
4)从当前为止移动到K+1个结点位置
5)继续执行1)
6)如果执行了逆置,那么第一个K块中K-1个结点为新的表头结点,否则返回原表头结点
代码:
//获取第k+1个结点的指针
public static ListNode getKPlusOneThNode(int k, ListNode h) {
ListNode kth;
int i;
if(h == null) {
return h;
}
for(i = 0, kth = h; kth != null && i < k; i++, kth = kth.getNext());
if(i == k && kth != null) {
return kth;
}
return h.getNext();
}
//判断链表剩下的结点是否有k个
public static boolean hasKNodes(int k, ListNode h) {
int i;
for(i = 0; h != null && i < k; i++, h = h.getNext());
if(i == k) {
return true;
}
return false;
}
public static ListNode reverseKNodeLink(ListNode h, int k) {
ListNode temp, next, cur = h, newNode, l;
if(k == 0 || k == 1) {
return h;
}
//若第一个K块存在,则修改头指针
if(hasKNodes(k - 1, cur)) {
newNode = getKPlusOneThNode(k - 1, cur);
} else {
newNode = h;
}
//判断链表剩余部分是否还有K块
while(cur != null && hasKNodes(k, cur)) {
l = cur;//l指向K块的第一个结点,并且逆置后成为最后一个
temp = getKPlusOneThNode(k, cur);//temp指向K块的最后一个结点,并且逆置后成为第一个
int i = 0;
//逆置
while(i < k) {
next = cur.getNext();
cur.setNext(temp);
temp = cur;
cur = next;
i++;
}
//逆置之后若后面还有K块,则需要调整当前块的最后一个结点l指向下一块的逆置后的第一个结点
if(hasKNodes(k, cur)) {
l.setNext(getKPlusOneThNode(k - 1, cur));
}
}
return newNode;
}
在这里一定要记得改指针的指向,尤其是前一个块逆置后的最后一个结点指向后一个块逆置后的第一个结点,这块一定要记得修改,否则就会缺失数据
这是修改后得:
若没有添加
if(hasKNodes(k, cur)) {
l.setNext(getKPlusOneThNode(k - 1, cur));
}
则后面的链表为: