本系列所选题目均来自力扣或者牛客网站. 所选题目主要是以其中的简单题为主, 中等题为辅, 包含少数困难题(原因是: 本人目前能力还不够~ ). 开展这个系列的目的是督促自己, 在暑假的时间里也要保持有一定的刷题量, 拒绝摆烂~
话不多说, 直接开刷~~
用户分组
题目描述: 有 n 个人被分成数量未知的组。每个人都被标记为一个从 0 到 n - 1 的唯一ID 。
给定一个整数数组 groupSizes ,其中 groupSizes[i] 是第 i 个人所在的组的大小。例如,如果 groupSizes[1] = 3 ,则第 1 个人必须位于大小为 3 的组中。
返回一个组列表,使每个人 i 都在一个大小为 groupSizes[i] 的组中。
每个人应该 恰好只 出现在 一个组 中,并且每个人必须在一个组中。如果有多个答案,返回其中 任何 一个。可以 保证 给定输入 至少有一个 有效的解。
解题思路:
(1) 这道题使用哈希桶的思想就可以简单解决.
(2) 遍历数组, 将数组中的每一个元素添加到哈希表中对应 key 值的链表后面. 这里需要注意, 如若 key 值中没有链表存在(也就是第一次遍历到这个元素的时候), 那么需要先定义一个链表.
(3) 由于在一个链表下面, 可能会有超过 key 值大小的节点存在, 那么这时候我们的解决方法是: 在每次往链表中添加节点之后, 判断当前链表的大小是否与对应的 key 值相等, 如若相等, 则可以先将这整个链表上所有节点都存到顺序表中, 然后将链表清空即可. 直到把数组遍历完, 返回顺序表即可.
实现代码:
class Solution {
public List<List<Integer>> groupThePeople(int[] groupSizes) {
Map<Integer, List<Integer>> map = new HashMap<>();
List<List<Integer>> ret = new ArrayList<>();
int len = groupSizes.length;
for(int i = 0; i < len; i++){
int x = groupSizes[i];
if(map.get(x) == null){
map.put(x, new ArrayList<>());
}
map.get(x).add(i);
if(map.get(x).size() == x){
ret.add(map.get(x));
map.put(x, null);
}
}
return ret;
}
}
K个一组翻转链表
题目描述: 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
解题思路:
(1) 这道题我使用的是比较容易实现(不容易出错)的做法 — 使用栈来实现, 但是这种做法的时间复杂度和空间复杂度是会比较大的.
(2) 每次将原链表的前 k 个节点添加到栈中, 然后再取出这些节点拼接到一个新的链表后面, 这样就可以实现 k 个为一组来进行翻转. 直到原链表遍历到 null 的时候.
(3) 直到最后剩下的节点可能会不够 k 个, 就不能进行翻转, 那么这时候, 每位只需要再定义一个栈来再次将这些节点翻转一遍即可(翻转两次就相当于没执行翻转).
(4) 有一点需要注意: 我们不是在原链表遍历到 null 的时候, 就判断它一定是不进行翻转的, 因为还可能会有一种情况, 当链表遍历到 null 的时候, 刚好是构成一组的(也就是刚好是 k 个节点), 所以还有把这种情况排除在外.
(5) 还有一点值得注意的是: 我们在编写下面这段代码的时候, 这里的 if 语句是不能够省略的.
while(!stack.empty()){
cur.next = stack.pop();
cur = cur.next;
if(stack.empty()){
cur.next = null;
}
}
原因是: 如果去掉, 就可能会有一些测试用例是不通过的, 会因为返回的链表是一个(死)循环而报错(可以自己调试看看最终效果), 所以我们每次都需要手动地将最后一个节点的 next 值设为 null, 如此一来, 就万无一失了.
实现代码:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode Head = new ListNode();
ListNode cur = Head;
Stack<ListNode> stack = new Stack<>();
Stack<ListNode> st = new Stack<>();
while(head != null){
int count = k;
while(count > 0 && head != null){
stack.push(head);
head = head.next;
count--;
}
if(head != null || (head == null && count == 0)){
while(!stack.empty()){
cur.next = stack.pop();
cur = cur.next;
if(stack.empty()){
cur.next = null;
}
}
}else{
while(!stack.empty()){
st.push(stack.pop());
}
while(!st.empty()){
cur.next = st.pop();
cur = cur.next;
if(stack.empty()){
cur.next = null;
}
}
}
}
return Head.next;
}
}