LeetCode第 86 场双周赛

简介: LeetCode第 86 场双周赛

第86场双周赛情况


地址:第86场双周赛



战绩:



第三题案例还差两个过了:



最后的情况:真太菜了



目前竞赛分数:



题目复盘+题解


题1:6171. 和相等的子数组【easy】


题目链接:6171. 和相等的子数组


题目内容:


给你一个下标从 0 开始的整数数组 nums ,判断是否存在 两个 长度为 2 的子数组且它们的 和 相等。注意,这两个子数组起始位置的下标必须 不相同 。
如果这样的子数组存在,请返回 true,否则返回 false 。
子数组 是一个数组中一段连续非空的元素组成的序列。
示例 1:
输入:nums = [4,2,4]
输出:true
解释:元素为 [4,2] 和 [2,4] 的子数组有相同的和 6 。
示例 2:
输入:nums = [1,2,3,4,5]
输出:false
解释:没有长度为 2 的两个子数组和相等。
示例 3:
输入:nums = [0,0,0]
输出:true
解释:子数组 [nums[0],nums[1]] 和 [nums[1],nums[2]] 的和相等,都为 0 。
注意即使子数组的元素相同,这两个子数组也视为不相同的子数组,因为它们在原数组中的起始位置不同。
提示:
2 <= nums.length <= 1000
-109 <= nums[i] <= 109


复盘:当时题目没有读清楚,其实就是连续子数组两个 + 两数和相等不同情况,最终就是求方案数。我耗费了一大堆时间就是因为题目没有理解清楚。


思路:


1、利用哈希


复杂度分析:时间复杂度O(n);空间复杂度O(1)


class Solution {
    //连续的子数组
    public boolean findSubarrays(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int i = 1; i < nums.length; i++) {
            int val = nums[i - 1] + nums[i];
            if (set.contains(val)) {
                return true;
            }
            set.add(val);
        }
        return false;
    }
}



题2:6172. 严格回文的数字【medium】


题目链接:6172. 严格回文的数字


题目内容:


如果一个整数 n 在 b 进制下(b 为 2 到 n - 2 之间的所有整数)对应的字符串 全部 都是 回文的 ,那么我们称这个数 n 是 严格回文 的。
给你一个整数 n ,如果 n 是 严格回文 的,请返回 true ,否则返回 false 。
如果一个字符串从前往后读和从后往前读完全相同,那么这个字符串是 回文的 。
示例 1:
输入:n = 9
输出:false
解释:在 2 进制下:9 = 1001 ,是回文的。
在 3 进制下:9 = 100 ,不是回文的。
所以,9 不是严格回文数字,我们返回 false 。
注意在 4, 5, 6 和 7 进制下,n = 9 都不是回文的。
示例 2:
输入:n = 4
输出:false
解释:我们只考虑 2 进制:4 = 100 ,不是回文的。
所以我们返回 false 。
提示:
4 <= n <= 105



思路:


1、左右拆分


复杂度分析:时间复杂度O(n);空间复杂度O(1)


class Solution {
    //n表示[2, n - 2]进制,判断是否是回文
    public boolean isStrictlyPalindromic(int n) {
        //i表示几位进制数
        for (int i = 2; i < n - 1; i++) {
            if (n % i == 0) {
                return false;
            }
            //拆成左右两边
            int leftVal = n / 2;
            int rightVal = n - leftVal;
            if (leftVal % i == 0 || rightVal % i == 0) {
                return false;
            }
        }
        return true;
    }
}



2、数学证明(推荐)


参考:数学证明-灵茶山艾府


思路:


根据题目得知:2 <= b <= n-2,b表示的是进制数,而n表示的是某个数字,对应范围n给出了4 <= n <= 105
对于在任意进制b的情况下我们都可以使用一个公式来表示:n = q*b + r,并且其中的0 <= r < b
我们来列举一些案例:
n = 4
  b = 2   =>  100 (不成立)
n = 5
  b = 2   =>  101 (成立)
  b = 3   =>  12 (不成立)
n = 6
  b = 2   =>  110(不成立)
  b = 3   =>  20(不成立)
  b = 4   =>  12(不成立)
n = 7
  b = 2   =>  111(成立)
  b = 3   =>  21(不成立)
  b = 4   =>  13(不成立)
  b = 5   =>  12(不成立)
n = 8
  b = 2   =>  1000(不成立)
  b = 3   =>  22(不成立)
  b = 4   =>  20(不成立)
  b = 5   =>  13(不成立)
  b = 6   =>  12(不成立)
你发现了什么,当n>4的时候,当b进制为n-2时,每个数的b进制数都是12,那么可以得出结论
当n > 4时,b=n-2时结果值为12,不是回文数
当n = 4时,不是回文数
由此,我们最后无需进行进制运算,最后直接返回false即可。



复杂度分析:时间复杂度O(1);空间复杂度O(1)


class Solution {
    public boolean isStrictlyPalindromic(int n) {
        return false;
    }
}



题3:6173. 被列覆盖的最多行数【medium】


题目链接:6173. 被列覆盖的最多行数


题目内容:


给你一个下标从 0 开始的 m x n 二进制矩阵 mat 和一个整数 cols ,表示你需要选出的列数。
如果一行中,所有的 1 都被你选中的列所覆盖,那么我们称这一行 被覆盖 了。
请你返回在选择 cols 列的情况下,被覆盖 的行数 最大 为多少。


复盘:在调试过程中,我为了过一个例子,竟然加了一个校验条件,导致我最后两个案例没过,其实最后的全排列函数中我的代码是没有问题的,之后再进行调试时不能乱加一些无意义的校验代码,说多了都是累啊,本来第三题也能过的!



思路:


1、全排列+哈希表+回溯


复杂度分析:时间复杂度O(n!*m*n),空间复杂度O(n!)


class Solution {
    public int maximumRows(int[][] mat, int cols) {
        if (mat.length == cols) {
            return cols;
        }
        quanpailie(mat, cols, 0, new HashSet<>());
        return max;
    }
    private int max = -1;
    //res存储的是对应的列方案
    public void quanpailie(int[][] mat, int cols, int col, Set<Integer> res) {
if (res.size() == cols) {
            int num = 0;
            //实际来进行处理操作
            for (int i = 0; i < mat.length; i++) {
                boolean flag = true;
                for (int j = 0; j < mat[0].length; j++) {
                    if (!res.contains(j) && mat[i][j] == 1) {
                        flag = false;
                        break;
                    }
                }
                if (flag) num++;
            }
            if (num > max) max = num;
            return;
        }
        for (int i = col; i < mat[0].length; i++) {
            res.add(i);
            quanpailie(mat, cols, i + 1, res);
            res.remove(i);
        }
    }
}




题4:预算内的最多机器人数目【hard】


题目链接:6143. 预算内的最多机器人数目


题目内容:


你有 n 个机器人,给你两个下标从 0 开始的整数数组 chargeTimes 和 runningCosts ,两者长度都为 n 。第 i 个机器人充电时间为 chargeTimes[i] 单位时间,花费 runningCosts[i] 单位时间运行。再给你一个整数 budget 。
运行 k 个机器人 总开销 是 max(chargeTimes) + k * sum(runningCosts) ,其中 max(chargeTimes) 是这 k 个机器人中最大充电时间,sum(runningCosts) 是这 k 个机器人的运行时间之和。
请你返回在 不超过 budget 的前提下,你 最多 可以 连续 运行的机器人数目为多少。
示例 1:
输入:chargeTimes = [3,6,1,3,4], runningCosts = [2,1,3,4,5], budget = 25
输出:3
解释:
可以在 budget 以内运行所有单个机器人或者连续运行 2 个机器人。
选择前 3 个机器人,可以得到答案最大值 3 。总开销是 max(3,6,1) + 3 * sum(2,1,3) = 6 + 3 * 6 = 24 ,小于 25 。
可以看出无法在 budget 以内连续运行超过 3 个机器人,所以我们返回 3 。
示例 2:
输入:chargeTimes = [11,12,19], runningCosts = [10,8,7], budget = 19
输出:0
解释:即使运行任何一个单个机器人,还是会超出 budget,所以我们返回 0 。
提示:
chargeTimes.length == runningCosts.length == n
1 <= n <= 5 * 104
1 <= chargeTimes[i], runningCosts[i] <= 105
1 <= budget <= 1015


思路:


1、大顶堆+双指针


复杂度分析:时间复杂度O(n);空间复杂度O(n)


class Solution {
    //chargeTimes  充电时间
    //runningCosts 运行时间
    //开销  max(chargeTimes) + k * sum(runningCosts)
    //budget 运算
    //考虑问题:连续n个数中的最大值(优先队列,大顶堆) +  双指针
    public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) {
        int ans = 0;
        long cost = 0, sum = 0;
        int n = chargeTimes.length;
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1, o2)->o2 - o1);
        for (int l = 0, r = 0; r < n; r++) {
            while (cost > budget) {
                //减去当前的
                sum -= runningCosts[l];
                maxHeap.remove(chargeTimes[l]);
                l++;
                if (!maxHeap.isEmpty()) {
                    cost = maxHeap.peek() + sum * (r - l + 1);
                }else {
                    cost = 0;
                }
            }
            //重新计算新的值
            sum += runningCosts[r];
            maxHeap.add(chargeTimes[r]);
            cost = maxHeap.peek() + sum * (r - l + 1);
            if (cost <= budget) {
                ans = Math.max(ans, r - l + 1);
            }
        }
        return ans;
    }
}


相关文章
|
6月前
Leetcode第123场双周赛
在LeetCode的第123场双周赛中,参赛者需解决三个问题。第一题涉及根据给定数组构建三角形并判断其类型,如等边、等腰或不等边,代码实现通过排序简化条件判断。第二题要求找出满足差值为k的好子数组的最大和,解决方案利用前缀和与哈希表提高效率。第三题则需要计算点集中满足特定条件的点对数量,解题策略是对点按坐标排序并检查点对是否满足要求。
26 1
|
6月前
力扣双周赛 -- 117(容斥原理专场)
力扣双周赛 -- 117(容斥原理专场)
【Leetcode】- 第 29 场双周赛
【Leetcode】- 第 29 场双周赛
|
机器人
LeetCode 双周赛 106(2023/06/10)两道思维题
往期回顾:[LeetCode 单周赛第 348 场 · 数位 DP 模版学会了吗?](https://mp.weixin.qq.com/s/4aLHpyaLOUEHSaX2X8e5FQ)
87 0
LeetCode 双周赛 106(2023/06/10)两道思维题
|
算法 索引
LeetCode 双周赛 107(2023/06/24)滑动窗口与离散化
> **本文已收录到 [AndroidFamily](https://github.com/pengxurui/AndroidFamily),技术和职场问题,请关注公众号 \[彭旭锐] 和 \[BaguTree Pro] 知识星球提问。**
74 0
LeetCode 双周赛 107(2023/06/24)滑动窗口与离散化
|
边缘计算 缓存 算法
LeetCode 双周赛 102,模拟 / BFS / Dijkstra / Floyd
昨晚是 LeetCode 双周赛第 102 场,你参加了吗?这场比赛比较简单,拼的是板子手速,继上周掉大分后算是回了一口血 😁。
111 0
|
人工智能 算法 测试技术
LeetCode 双周赛 101,DP / 中位数贪心 / 裴蜀定理 / Dijkstra / 最小环
这周比较忙,上周末的双周赛题解现在才更新,虽迟但到哈。上周末这场是 LeetCode 第 101 场双周赛,整体有点难度,第 3 题似乎比第 4 题还难一些。
98 0
|
存储 数据安全/隐私保护