题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
通过次数56,434
提交次数95,949
来源:力扣(LeetCode)
链接: https://leetcode-cn.com/problems/reverse-nodes-in-k-group.
思路:
此题多种解法,这里采用栈的思想进行讲解。
那么。什么是栈呢?
栈的最典型特点就是后进先出
用下图来描述会更好理解:
从图中可以清晰的看出,先入栈的元素被压入栈底,只有当栈顶元素都出栈后它才能出栈!
此题要将链表的k个节点进行反转,可以采用入栈出栈的方式,先·入栈的最后出栈,从而达到反转链表的目的!
java实现:
/**
* 使用栈实现
* @param head
* @param k
* @return
*/
public ListNode reverseKGroup(ListNode head, int k) {
//定义一个栈
Stack<ListNode> stack=new Stack<ListNode>();
//初始化一个新的链表存放结果
ListNode ret = new ListNode(0);
//为新链表定义一个指针,防止后续操作改变链表头节点
ListNode p = ret;
//循环原有链表
while (true){
//为每次反转计数
int count=0;
//定义指针操作原始链表
ListNode tmp = head;
//循环入栈
while (tmp!=null&&count<k){
stack.push(tmp);
tmp=tmp.next;
count++;
}
//判断该次反转是否达到要求,此处防止因tem==null跳出循环的条件
if (count!=k){
//表示剩下的节点不够k个,直接将剩余节点插入末尾结束
p.next=head;
break;
}
//出栈操作,反转链表
while (!stack.isEmpty()){
p.next=stack.pop();
p = p.next;
}
//重置下一次操作的初始节点
p.next=tmp;
head=tmp;
}
return ret.next;
}
小结
此题为力扣题目中的困难题。这是其中的一种解法。另外还可以通过尾插法,递归实现。不过我认为用栈来解题比较好理解。不过建议小伙伴们还是要去了解一下尾插法解题,这也是链表中的一种经典算法!