这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
今天是8月16日,本月有31天,今天写完,这个月的活动也完成过半了。
这2周除了工作上,其他的事情都还挺好的,每天写一篇文章,每周锻炼5天,每次至少30分钟,立下的几个Flag都没有倒。最近看了一些二手车的短视频,发现一个特别明显的现象:越是高端的二手车买卖,越是平淡,人物也更加彬彬有礼,交易中也更有信任感;越是低端的二手车交易,故事越是曲折离奇,有很多坑,充满了尔虞我诈,情节的戏剧性很难让人相信这是真实发生的事情。其实仔细想想,可能是针对了2种不同的人群,底层的人更加爱看这些冲突,他们生活的世界里面,这样连环坑的事情也更加常见,符合他们的世界观;高层的人更加平和,更多是看看车,认识交易的人,有了信任感之后,交易是更加自然而然的结果。所以,当你自己想要抱怨的时候,可能更应该反思一下,是不是自己能量还不够足,层次还不够高,所以周边环境显得更加恶劣,向内归因提升自己,是跳出恶劣环境的艰难的路,同时也是最近的捷径。
想了这么多,继续刷题精进技术吧,今天做leetcode的第25题。
题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
示例 3:
输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]
示例 4:
输入:head = [1], k = 1
输出:[1]
思路
分成长度为k的小链表,最后1个分组可能会不足k个。对这k个小链表,做完全反转,然后再收尾相接起来,最后不足k个的小链表,不用反转,直接追加在最后面。如下图所示
小链表自身完全反转的方法:
- 定义1个pre节点为空,定义1个current节点指向头节点
- 记录current的next节点为next
- current的next指向pre
- current作为pre,next作为current
- 循环2-4,直到链表结束
Java版本代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode();
ListNode tail = dummy;
ListNode index = head;
while (index != null) {
if (hasKListNode(index, k)) {
// 剩余大于等于k个节点
// 记录现在小链表的头结点
ListNode subHead = index;
// index向后走k个节点
for (int i = 0; i < k; i++) {
index = index.next;
}
// 反转小链表,tail的next指向新小链表的头节点
tail.next = reverseKListNode(subHead, k);
// 原小链表的头结点是最新结果链表的尾结点,就是最新的tail
tail = subHead;
} else {
// 剩余不足k个节点
// 当前尾结点的next指向剩余的头结点
tail.next = index;
break;
}
}
return dummy.next;
}
/**
* 是否包含k个节点
*
* @param index
* @param k
* @return
*/
private static boolean hasKListNode(ListNode index, int k) {
while (k-- > 0) {
if (index == null) {
return false;
}
index = index.next;
}
return true;
}
/**
* 反转链表
*
* @param head
* @param len
* @return
*/
private static ListNode reverseKListNode(ListNode head, int len) {
ListNode pre = null;
ListNode current = head;
while (len-- > 0) {
ListNode next = current.next;
current.next = pre;
pre = current;
current = next;
}
// 此时pre是新的链表的头结点
return pre;
}
}