• [每日两题系列]刷算法题咯~~


            本系列所选题目均来自力扣或者牛客网站. 所选题目主要是以其中的简单题为主, 中等题为辅, 包含少数困难题(原因是: 本人目前能力还不够~ ). 开展这个系列的目的是督促自己, 在暑假的时间里也要保持有一定的刷题量, 拒绝摆烂~
            话不多说, 直接开刷~~

    用户分组

            题目描述: 有 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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

            原因是: 如果去掉, 就可能会有一些测试用例是不通过的, 会因为返回的链表是一个(死)循环而报错(可以自己调试看看最终效果), 所以我们每次都需要手动地将最后一个节点的 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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    in(...) 可能会让你排查Bug到崩溃,哈哈哈
    mongodb使用debezium
    在CentOS7下安装Oracle11教程
    React-native Android 添加音效
    18【PreparedStatement接口详细解析】
    linux内网服务器设置全局代理和yum代理
    算数平均法和加权平均法
    Linux权限维持
    特征工程设计思路
    Tomcat信创平替之TongWEB(东方通),安装步骤
  • 原文地址:https://blog.csdn.net/Faith_cxz/article/details/126312708