🚀竞赛
使每一列严格递增的最少操作次数 做题过程 一次提交失败,因为之前只考虑了升序的情况。
算法概述 本题要求为将给出二维矩阵中的每一列变为升序,每次操作可对某一列中元素自增一次,计算最少操作次数。直接模拟即可。
JAVA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minimumOperations (int [][] grid) { int ans = 0 ; for (int i = 0 ; i != grid[0 ].length; ++i) { int max=grid[0 ][i]; for (int j = 1 ; j != grid.length; ++j) { if (max<grid[j][i]) max=grid[j][i]; else { ans+=max-grid[j][i]+1 ; max++; } } } return ans; } }
总结 没有考虑好不同顺序的情况,想当然的直接提交了,喜提一次wa
从盒子中找出字典序最大的字符串 I 做题过程 三次wa,没把情况考虑全,反反复复的追求过当前测试用例。但是完成时间在35分钟,还行。
算法概述 本题要求为按照给定个数划分字符串,全部可能划分完之后,找出字典序最大的字符串(即各个位上的字母顺序比较,完全相同则比较长度)。
JAVA 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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 class Solution { public String answerString (String word, int numFriends) { if (numFriends==1 ) return word; int longest=word.length()-numFriends+1 ; char max=word.charAt(0 ); for (int i=1 ;i!=word.length();++i){ if (max<word.charAt(i)){ max=word.charAt(i); } } List<Integer> subs=new ArrayList <>(); for (int i=0 ;i!=word.length();++i){ if (word.charAt(i)==max) subs.add(i); } List<String> strs=new ArrayList <>(); for (int i=0 ;i!=subs.size();++i){ int seq=subs.get(i); if (seq+longest<=word.length()) strs.add(word.substring(seq,seq+longest)); else strs.add(word.substring(seq)); } strs.sort((a,b)->{ for (int i=0 ;i!=Math.min(a.length(),b.length());++i){ if (a.charAt(i)!=b.charAt(i)) return b.charAt(i)-a.charAt(i); } return b.length()-a.length(); }); return strs.get(0 ); } } class Solution { public String answerString (String s, int k) { if (k == 1 ) { return s; } int n = s.length(); String ans = "" ; for (int i = 0 ; i < n; i++) { String sub = s.substring(i, Math.min(i + n - k + 1 , n)); if (sub.compareTo(ans) > 0 ) { ans = sub; } } return ans; } }
重要实例方法及属性(JAVA) compareTo()
:对字符串来讲,这个就是直接比较字典顺序
总结 还有一种后缀计算的方法,是源于一道困难题的,还没做到,就写不看了。
统计特殊子序列的数目 做题过程 大部分时间都花在这里了,也没做出来,最无语的是不知道哪里错了,难绷。
算法概述 本题要求为找到特殊子序列,该特殊子序列[p, q, r, s]中满足: 且需要注意的是目标为 子序列 。以下解法均参考灵神(灵茶山艾府)。
解法一:
解法二:
JAVA 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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 class Solution { public long numberOfSubsequences (int [] nums) { int n = nums.length; Map<Integer, Integer> suf = new HashMap <>(); for (int i = 4 ; i < n - 2 ; i++) { int c = nums[i]; for (int j = i + 2 ; j < n; j++) { int d = nums[j]; int g = gcd(c, d); suf.merge((d / g) << 16 | (c / g), 1 , Integer::sum); } } long ans = 0 ; for (int i = 2 ; i < n - 4 ; i++) { int b = nums[i]; for (int j = 0 ; j < i - 1 ; j++) { int a = nums[j]; int g = gcd(a, b); ans += suf.getOrDefault((a / g) << 16 | (b / g), 0 ); } int c = nums[i + 2 ]; for (int j = i + 4 ; j < n; j++) { int d = nums[j]; int g = gcd(c, d); suf.merge((d / g) << 16 | (c / g), -1 , Integer::sum); } } return ans; } private int gcd (int a, int b) { while (a != 0 ) { int tmp = a; a = b % a; b = tmp; } return b; } } 作者:灵茶山艾府 链接:https: 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 class Solution { public long numberOfSubsequences (int [] nums) { int n = nums.length; long ans = 0 ; Map<Float, Integer> cnt = new HashMap <>(); for (int i = 4 ; i < n - 2 ; i++) { float b = nums[i - 2 ]; for (int j = 0 ; j < i - 3 ; j++) { cnt.merge(nums[j] / b, 1 , Integer::sum); } float c = nums[i]; for (int j = i + 2 ; j < n; j++) { ans += cnt.getOrDefault(nums[j] / c, 0 ); } } return ans; } } 作者:灵茶山艾府 链接:https: 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
重要实例方法及属性(JAVA)
Map.merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)
:先查找key
,不存在则插入key
和value
的键值对,如存在,则使用remappingFunction
合并key
查找的结果和value
的值
总结 总而言之,思路如下:
解法一:
先枚举c
和d
,通过 除以最大公约数 的方法使它们的分数最简,存入哈希表
再枚举a
和b
,在哈希表中通过查找相同的最简分数进行匹配,更新ans
同时还需要减少之前统计当前a
和b
组合能匹配到的的c
和d
计数,因为已经被用于匹配过了,注意c
是从i+2
开始,正好和b
的位置是匹配的,所以这个撤销操作是必须的
解法二:
以c
为枚举的核心
枚举之前的b
,再通过b
来枚举之前的a
,这里的b
是和c
一起动的,只有a
会出现重复遍历的情况
d
遍历方式和a
相同
suf.merge((d / g) << 16 | (c / g), 1, Integer::sum);
还有这种存储最简分数的方式更为高效且精度更高(虽然说下面的解法说明了浮点数也是可以用的)
统计恰好有K个相邻元素的数组数目 算法概述 本题要求为给出n, m, k,要求数组长度为n,有k个下标满足arr[i - 1] == arr[i],且每个元素都在[1, m]内。就是把n-1-k个不同的数看作切割线,那么就把这个问题变成排列组合了。
大概就是这个公式
PYTHON 1 2 3 4 5 6 7 8 9 10 11 class Solution : def countGoodArrays (self, n: int , m: int , k: int ) -> int : MOD = 1_000_000_007 return comb(n - 1 , k) % MOD * m * pow (m - 1 , n - k - 1 , MOD) % MOD 作者:灵茶山艾府 链接:https://leetcode.cn/problems/count-the-number-of-arrays-with -k-matching-adjacent-elements/solutions/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
总结 碰到数学的,要是推出来,就用python吧😊。