第 254 场力扣周赛

稀里糊涂双眼双眼惺忪的做了三道,错了4次。。。还是600来名

5843. 作为子字符串出现在单词中的字符串数目

题目描述

给你一个字符串数组 patterns 和一个字符串 word ,统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。

子字符串 是字符串中的一个连续字符序列。

示例 1:

输入:patterns = [“a”,“abc”,“bc”,“d”], word = “abc”
输出:3
解释:

  • “a” 是 “abc” 的子字符串。
  • “abc” 是 “abc” 的子字符串。
  • “bc” 是 “abc” 的子字符串。
  • “d” 不是 “abc” 的子字符串。
    patterns 中有 3 个字符串作为子字符串出现在 word 中。

示例 2:

输入:patterns = [“a”,“b”,“c”], word = “aaaaabbbbb”
输出:2
解释:

  • “a” 是 “aaaaabbbbb” 的子字符串。
  • “b” 是 “aaaaabbbbb” 的子字符串。
  • “c” 不是 “aaaaabbbbb” 的字符串。
    patterns 中有 2 个字符串作为子字符串出现在 word 中。

示例 3:

输入:patterns = [“a”,“a”,“a”], word = “ab”
输出:3
解释:patterns 中的每个字符串都作为子字符串出现在 word “ab” 中。

提示:

1 <= patterns.length <= 100
1 <= patterns[i].length <= 100
1 <= word.length <= 100
patterns[i] 和 word 由小写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-strings-that-appear-as-substrings-in-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

子串问题,忘了java中有哪个API可以用了,然后第一道写了十分钟,麻了

class Solution {public int numOfStrings(String[] patterns, String word) {int res = 0;int l = patterns.length;int lw = word.length();for(int i = 0; i < l; i++){String s = patterns[i];int k = 0;boolean flag = false;for(int j = 0; j < lw; j++){char c = word.charAt(j);int temp = j;while(k < s.length() && j < lw && word.charAt(j) == s.charAt(k)){j++;k++;if(k == s.length()){flag = true;break;}}if(flag)break;k = 0;j = temp;}if(flag)res++;}return res;}
}

调contians方法,五行…

class Solution {public int numOfStrings(String[] patterns, String word) {int res = 0;for(String s : patterns){if(word.contains(s))res++;}return res;}
}

或者indexOf方法

class Solution {public int numOfStrings(String[] patterns, String word) {int res = 0;for(String s : patterns){if(word.indexOf(s) != -1)res++;}return res;}
}

KMP再练一手:

class Solution {public int numOfStrings(String[] patterns, String word) {int res = 0;for(String s : patterns){int[] next = getNext(s);if(kmp(word, s, next))res++;}return res;}//首先,关键点,构建next的数组,是表示前后缀部分是否有相同public int[] getNext(String s){int l = s.length();int[] next = new int[l];int j = 0;for(int i = 1; i < l; i++){while(j > 0 && s.charAt(i) != s.charAt(j)){j = next[j - 1];}if(s.charAt(i) == s.charAt(j))j++;next[i] = j;}return next;}   public boolean kmp(String s, String t, int[] next){int ls = s.length();int lt = t.length();int j = 0;for(int i = 0; i < ls; i++){while(j > 0 && s.charAt(i) != t.charAt(j)){j = next[j - 1];}if(s.charAt(i) == t.charAt(j))j++;if(j == lt)return true;}return false;}
}

5832. 构造元素不等于两相邻元素平均值的数组

题目描述

给你一个 下标从 0 开始 的数组 nums ,数组由若干 互不相同的 整数组成。你打算重新排列数组中的元素以满足:重排后,数组中的每个元素都 不等于 其两侧相邻元素的 平均值 。

更公式化的说法是,重新排列的数组应当满足这一属性:对于范围 1 <= i < nums.length - 1 中的每个 i ,(nums[i-1] + nums[i+1]) / 2 不等于 nums[i] 均成立 。

返回满足题意的任一重排结果。

示例 1:

输入:nums = [1,2,3,4,5]
输出:[1,2,4,5,3]
解释:
i=1, nums[i] = 2, 两相邻元素平均值为 (1+4) / 2 = 2.5
i=2, nums[i] = 4, 两相邻元素平均值为 (2+5) / 2 = 3.5
i=3, nums[i] = 5, 两相邻元素平均值为 (4+3) / 2 = 3.5

示例 2:

输入:nums = [6,2,0,9,7]
输出:[9,7,6,2,0]
解释:
i=1, nums[i] = 7, 两相邻元素平均值为 (9+6) / 2 = 7.5
i=2, nums[i] = 6, 两相邻元素平均值为 (7+2) / 2 = 4.5
i=3, nums[i] = 2, 两相邻元素平均值为 (6+0) / 2 = 3

提示:

3 <= nums.length <= 10^5
0 <= nums[i] <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/array-with-elements-not-equal-to-average-of-neighbors
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

当时一层循环过不了,两层循环过了,都不知道为啥就过了,实际不太懂怎么做

class Solution {public int[] rearrangeArray(int[] nums) {//就是不是一个等差数列呗int l = nums.length;Arrays.sort(nums);for(int i = 1; i < l - 1; i++){if(nums[i + 1] - nums[i] == nums[i] - nums[i - 1])swap(nums, i - 1, i);}for(int i = 1; i < l - 1; i++){if(nums[i + 1] - nums[i] == nums[i] - nums[i - 1])swap(nums, i - 1, i);}return nums;}public void swap(int[] nums, int x, int y){int temp = nums[x];nums[x] = nums[y];nums[y] = temp;}
}

然后出来看了一下大佬们的思想:
排序,然后将数组分成小数、大数两部分,然后小、大、小、大穿插着放
其实报错的示例就是这么安排的,但是我当时没仔细看错了给定正确答案,我还以为是随便排的
又学到了一个小技巧

class Solution {public int[] rearrangeArray(int[] nums) {Arrays.sort(nums);int l = nums.length;int[] res = new int[l];int idx = 0;for(int i = 0; i < l; i += 2){res[i] = nums[idx++]; }for(int i = 1; i < l; i += 2){res[i] = nums[idx++];}return res;}
}

或者直接交换相邻位置

class Solution {public int[] rearrangeArray(int[] nums) {//直接交换相邻位,道理还是那个//交换以后,会形成大小大小大...这种形式Arrays.sort(nums);int l = nums.length;for(int i = 0; i < l - 1; i += 2){int temp = nums[i];nums[i] = nums[i + 1];nums[i + 1] = temp;}return nums;}
}

5844. 数组元素的最小非零乘积

题目描述

给你一个正整数 p 。你有一个下标从 1 开始的数组 nums ,这个数组包含范围 [1, 2p - 1] 内所有整数的二进制形式(两端都 包含)。你可以进行以下操作 任意 次:

从 nums 中选择两个元素 x 和 y 。
选择 x 中的一位与 y 对应位置的位交换。对应位置指的是两个整数 相同位置 的二进制位。
比方说,如果 x = 1101 且 y = 0011 ,交换右边数起第 2 位后,我们得到 x = 1111 和 y = 0001 。

请你算出进行以上操作 任意次 以后,nums 能得到的 最小非零 乘积。将乘积对 109 + 7 取余 后返回。

注意:答案应为取余 之前 的最小值。

示例 1:

输入:p = 1
输出:1
解释:nums = [1] 。
只有一个元素,所以乘积为该元素。

示例 2:

输入:p = 2
输出:6
解释:nums = [01, 10, 11] 。
所有交换要么使乘积变为 0 ,要么乘积与初始乘积相同。
所以,数组乘积 1 * 2 * 3 = 6 已经是最小值。

示例 3:

输入:p = 3
输出:1512
解释:nums = [001, 010, 011, 100, 101, 110, 111]

  • 第一次操作中,我们交换第二个和第五个元素最左边的数位。
    - 结果数组为 [001, 110, 011, 100, 001, 110, 111] 。
  • 第二次操作中,我们交换第三个和第四个元素中间的数位。
    - 结果数组为 [001, 110, 001, 110, 001, 110, 111] 。
    数组乘积 1 * 6 * 1 * 6 * 1 * 6 * 7 = 1512 是最小乘积。

提示:

1 <= p <= 60

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-non-zero-product-of-the-array-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

看到最小乘积,当时想的是正方形面积最大,而两条边差距越大的话,面积越小
所以要想整体乘积越小,就得数之间的差距越大
而看到示例中的第三个也印证了我的想法
然后再找规律,给定p,那么共有2^p-1个数,最大数也是2^p-1
而剩下的数,都可以通过交换,变成1和2^p-2(用base代替)
所以总共就有(2^p-2) / 2(用x代替)个base
也就是base的x次方
因为数很大,刚开始我想用double算的,结果60弄进去,还是溢出了
最后只能快速幂,然后每次取余了

对了,乘法取余:(a×b) mod c=(a mod c * b mod c) mod c 记住

class Solution {public static final int MOD = (int)1.0e9 + 7;public int minNonZeroProduct(int p) {//使数尽可能在两边//最小是//前后4位不能动if(p == 1)return 1;if(p == 2)return 6;long t = (long)Math.pow(2, p);long x = (t - 3) / 2;long base = t - 2;long ret = mypow(base, x + 1);//System.out.println(t);ret = ((ret % MOD) * ((t - 1) % MOD)) % MOD;return (int)ret;}public long mypow(long base, long x){long res = 1;base = base % MOD;int t = 1;while(x != 0){if((x & 1) == 1){res = (res * (base % MOD)) % MOD;}x >>= 1;base = ((base % MOD) * (base % MOD)) % MOD;}return res;}
}

5845. 你能穿过矩阵的最后一天

题目描述

给你一个下标从 1 开始的二进制矩阵,其中 0 表示陆地,1 表示水域。同时给你 row 和 col 分别表示矩阵中行和列的数目。

一开始在第 0 天,整个 矩阵都是 陆地 。但每一天都会有一块新陆地被 水 淹没变成水域。给你一个下标从 1 开始的二维数组 cells ,其中 cells[i] = [ri, ci] 表示在第 i 天,第 ri 行 ci 列(下标都是从 1 开始)的陆地会变成 水域 (也就是 0 变成 1 )。

你想知道从矩阵最 上面 一行走到最 下面 一行,且只经过陆地格子的 最后一天 是哪一天。你可以从最上面一行的 任意 格子出发,到达最下面一行的 任意 格子。你只能沿着 四个 基本方向移动(也就是上下左右)。

请返回只经过陆地格子能从最 上面 一行走到最 下面 一行的 最后一天 。

示例 1:

输入:row = 2, col = 2, cells = [[1,1],[2,1],[1,2],[2,2]]
输出:2
解释:上图描述了矩阵从第 0 天开始是如何变化的。
可以从最上面一行到最下面一行的最后一天是第 2 天。

示例 2:

输入:row = 2, col = 2, cells = [[1,1],[1,2],[2,1],[2,2]]
输出:1
解释:上图描述了矩阵从第 0 天开始是如何变化的。
可以从最上面一行到最下面一行的最后一天是第 1 天。

示例 3:

输入:row = 3, col = 3, cells = [[1,2],[2,1],[3,3],[2,2],[1,1],[1,3],[2,3],[3,2],[3,1]]
输出:3
解释:上图描述了矩阵从第 0 天开始是如何变化的。
可以从最上面一行到最下面一行的最后一天是第 3 天。

提示:

2 <= row, col <= 2 * 10^4
4 <= row * col <= 2 * 10^4
cells.length == row * col
1 <= ri <= row
1 <= ci <= col
cells 中的所有格子坐标都是 唯一 的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/last-day-where-you-can-still-cross
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这道题我看范围,实在没想到用dfs能过,当时觉得dfs要走的情况很多,一直在想怎么把水域连成一条线啥的。。。
现在想想,也就是把所有方格里的点都遍历一次,复杂度也就是10的4次,在加个二分,肯定超时不了。。。失策了
这个题挺简单的

思路就是二分找能通过的天数,然后查看一天是否能通过,用bfs或者dfs

第一种:二分加多源bfs

class Solution {int[][] dir = {{0,1},{0,-1},{1,0},{-1,0}};public int latestDayToCross(int row, int col, int[][] cells) {int left = 0;int right = row * col;while(left < right){int mid = (right - left + 1) / 2 + left;//构建图int[][] graph = new int[row][col];//将水域赋值为1,是将mid这一天之前的水域for(int i = 0; i < mid; i++){//水域下标从1开始的int r = cells[i][0] - 1;int c = cells[i][1] - 1;graph[r][c] = 1;}boolean[][] used = new boolean[row][col];Queue<int[]> queue = new LinkedList<>();//将第一行的所有陆地加入队列中for(int i = 0; i < col; i++){if(graph[0][i] == 0)queue.offer(new int[]{0, i});used[0][i] = true;}//bfs找通路boolean found = false;while(!queue.isEmpty()){int[] point = queue.poll();for(int[] d : dir){int nx = point[0] + d[0];int ny = point[1] + d[1];if(nx >= 0 && nx < row && ny >= 0 && ny < col){//如果遍历过了,返回if(used[nx][ny])continue;//如果是水,跳过if(graph[nx][ny] == 1)continue;//如果到达了最后一行,返回if(nx == row - 1){found = true;break;}queue.offer(new int[]{nx, ny});used[nx][ny] = true;   }               }if(found)break;}//如果找到了通路,那么找右边if(found)left = mid;elseright = mid - 1;//System.out.println(left);}//输出的left是能走通的最后一天的下一天的下标,正好就是结果return left;}
}

并查集+时光倒流
复习一下并查集
思路:从后往前,将每一块新增的陆地放在并查集中,将和一个陆地相邻的陆地union起来,
因为第一行和最后一行走到就行,所以两个标志来表示第一行和最后一行是否到达过
如果第一行和最后一行连通了,那么就返回当前下标

class Solution {//并查集写一下int[][] dir = {{0,1},{0,-1},{1,0},{-1,0}};public int latestDayToCross(int row, int col, int[][] cells) {UnionFind uf = new UnionFind(row * col + 2);int S = row * col;      //表示第一行int T = S + 1;          //表示最后一行//表示当前点是否被加入了,只有被加入的点才能连通boolean[][] used = new boolean[row][col];for(int i = row * col - 1; i >= 0; i--){int x = cells[i][0] - 1;int y = cells[i][1] - 1;//这个点被加入了used[x][y] = true;int idx = x * col + y;//遍历四个方向for(int[] d : dir){int nx = x + d[0];int ny = y + d[1];//如果这个点在范围内,并且被加入过,那么将这两个点连通if(nx >= 0 && nx < row && ny >= 0 && ny < col && used[nx][ny]){//System.out.println(nx);uf.union(idx, nx * col + ny);}}//如果是第一行或者最后一行,将其连通if(x == 0)uf.union(idx, S);if(x == row - 1)uf.union(idx, T);//如果第一行和最后一行连通了if(uf.query(S, T)){return i;}}return -1;}
}class UnionFind{int[] parents;int n;int count;  //连通分量的数目int[] rank; //秩,表示和当前这个点连接的高度,相当于树的高度//构造器public UnionFind(int n){this.n = n;parents = new int[n];rank = new int[n];count = n;for(int i = 0; i < n; i++){parents[i] = i;rank[i] = 1;}}public void union(int x, int y) {int px = find(x);int py = find(y);if(px == py)return;//如果px连接的点少,那么就把px挂在py上if(rank[px] < rank[py]){parents[px] = py;}else if(rank[px] > rank[py]){parents[py] = px;}//如果秩相同,那么因为px挂在了py上,所以py的秩+1;if(rank[px] == rank[py]){parents[px] = py;rank[py]++;}count--;}public int find(int x){if(x != parents[x]){parents[x] = find(parents[x]);}return parents[x];}//查询x和y是否连通public boolean query(int x, int y){return find(x) == find(y);}
}

第 254 场力扣周赛(KMP、贪心、快速幂、二分+多源bfs、并查集 + 时光倒流)相关推荐

  1. LeetCode 第 58 场力扣夜喵双周赛(动态规划、马拉车算法,前后缀处理)/ 第 253 场力扣周赛(贪心,LIS)

    第 58 场力扣夜喵双周赛 两道600多 5193. 删除字符使字符串变好 题目描述 一个字符串如果没有 三个连续 相同字符,那么它就是一个 好字符串 . 给你一个字符串 s ,请你从 s 删除 最少 ...

  2. 第 256 场力扣周赛(状态压缩+dp,二进制子序列的动规、940)

    第 256 场力扣周赛 有事没做,来看一下题 5854. 学生分数的最小差值 题目描述 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整 ...

  3. 第 304 场力扣周赛

    1.Introduction 平常做代码题目较少,今天迟迟不能入睡,我思考了下,确实有很大概率,对十年内做的目标,有很大可能不能实现.于是做了几道题勉强让自己心安.一边喝着牛栏山壮精神,一边写Leet ...

  4. 第 270 场力扣周赛

    第一百一十二天 --- 第 270 场力扣周赛 题目一 思路:直接模拟 细节 代码 附加 题目二 思路 细节 代码 题目一 力扣:2094. 找出 3 位偶数 思路:直接模拟 1.因为构造所有三位数, ...

  5. 第 321 场力扣周赛

    第 321 场力扣周赛 T1 求和 class Solution { public:int pivotInteger(int n) {int sum=(1+n)*n/2;int cnt=0;for(i ...

  6. LeetCode第 57 场力扣夜喵双周赛(差分数组、单调栈) and 第 251 场力扣周赛(状态压缩动规,树的序列化,树哈希,字典树)

    LeetCode第 57 场力扣夜喵双周赛 离knight勋章越来越近,不过水平没有丝毫涨进 1941. 检查是否所有字符出现次数相同 题目描述 给你一个字符串 s ,如果 s 是一个 好 字符串,请 ...

  7. Leetcode周赛复盘——第 71 场力扣双周赛与第 279 场力扣周赛

    双周赛: 5984. 拆分数位后四位数字的最小和 class Solution:def minimumSum(self, num: int) -> int:a, b, c, d = sorted ...

  8. Leetcode周赛复盘——第 276 场力扣周赛

    第一次参加周赛,AC了三道题,也算不错的成绩了,从现在开始每周的周赛我都会参加并且复盘,有兴趣的小伙伴可以一起讨论. 5980. 将字符串拆分为若干长度为 k 的组 class Solution:de ...

  9. 第 342 场力扣周赛

    A 计算列车到站时间 模运算 class Solution {public:int findDelayedArrivalTime(int arrivalTime, int delayedTime) { ...

最新文章

  1. N 年沉淀,机器学习终于开源!
  2. Batch Normalization——加速深度神经网络收敛利器
  3. 用C#生成中文汉字验证码的基本原理
  4. 【Python成长之路】python 基础篇 -- 装饰器【华为云分享】
  5. 【软件工程实践 · 团队项目】 第二次作业
  6. Node.js下载安装及各种npm、nvm、nrm配置(保姆式教程---提供全套安装包)---node.js的安装与配置(1)
  7. angular4 浏览器兼容
  8. PTA 7-2 深入虎穴 (30 分)
  9. Unity3d面向英特尔® x86 平台的 Unity* 优化指南: 第 3 部分
  10. 如何实现多实验并行迭代,谈阿里妈妈的A/B测试实践
  11. 如何在SqlServer中获取前端连接的IP地址,计算机名等信息
  12. js基础-5-数据类型,作用域,优先级
  13. 微信小程序开发者下不验证https协议的操作
  14. 移植u-boot2020.04到原子哥的alpha开发板(三)
  15. 物联网教程 demo1效果
  16. 2022年全球市场工业缝纫机总体规模、主要生产商、主要地区、产品和应用细分研究报告
  17. Java+MySQL 基于Springboot+vue的旧物置换网站#毕业设计
  18. k线图入门与技巧:浪波理论与K线形态
  19. php使用PDO从数据库表中读取数据
  20. vue 多页面打包配置

热门文章

  1. std::ifstream实例
  2. Sublime的使用小技巧
  3. AAAI 2023 Fello名单出炉,李学龙教授完成AI 领域Fellow大满贯!
  4. 同步通讯和异步通讯的区别
  5. python将不同类型文件分开
  6. 洛谷P1477 假面舞会
  7. java中short类型变量
  8. 学习数据分析,数据分析必备的技能有哪些
  9. 最优化技术——单纯形法
  10. Flutter 混合开发 - 03 百度地图定位功能 ios 篇