funcmaximumBeauty(nums []int, k int)int { n := len(nums) sort.Ints(nums) d := make([]int, nums[n-1]+k+2) for _, num := range nums { d[max(0, num-k)] += 1 d[num+k+1] -= 1 } res := 0 sum := 0 for i := max(0, nums[0]-k); i < len(d); i++ { sum += d[i] res = max(res, sum) } return res }
funcmaximumBeauty2(nums []int, k int)int { sort.Ints(nums) left := 0 res := 1// 子数组最小长度为1 for right := 1; right < len(nums); right++ { for nums[right]-nums[left] > k*2 { left++ } res = max(res, right-left+1) } return res } funcmax(a, b int)int { if b > a { return b }; return a }
2780. 合法分割的最小下标
解题思路:
根据题意,切割出来的两个子数组中,支配元素相同,这里我们设支配元素为 x,从 i 处分割
对于第一个数组有:
freq(x)1×2>i+1
对于第二个数组有:
freq(x)2×n−i−1
由于这两个数组合并之后是原数组,所以:
freq(x)×2=freq(x)1×2+freq(x)2×2>(i+1)+(n−i−1)=n
首先求出支配元素 x 极其出现的次数 total,然后枚举 i ,一边枚举一边统计 freq1(x),那么 freq2(x)=total−freq1(x)。只要满足 freq1(x)×2>i+1 且 freq2(x)>n−i−1,就返回 i,没有这样的 i, 就返回 −1。
funcminimumIndex(nums []int)int { freq := map[int]int{} x := nums[0] for _, num := range nums { freq[num]++ if freq[num] > freq[x] { x = num } } total := freq[x] freq1 := 0 for i, num := range nums { if num == x { freq1++ } if freq1*2 > i+1 && (total-freq1)*2 > len(nums)-i-1 { return i } } return-1 }
当 right 右移到一个新字母时,枚举一该字母为右端点的 forbidden[i] 的最短长度(出现不合法时,left 就需要右移,最短可以保证 left 移动的效率),如果发现子串 word[i] 到 word[right] 在 forbidden 中,那么更新 left=i+1 并结束枚举,从而避免合法子串包含 forbidden 中的字符串。枚举结束后,更新答案为合法子串长度 right−left+1 的最大值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funclongestValidSubstring(word string, forbidden []string)int { m := make(map[string]bool, len(forbidden)) for _, s := range forbidden { m[s] = true } left := 0 res := 0 for right := range word { for i := right; i >= left && i > right-10; i-- { // forbidden中子串长度小于10 if m[word[i:right+1]] { left = i + 1 break } } res = max(res, right-left+1) } return res }