funcprintBin(num float64)string { s := strings.Builder{} s.WriteString("0.") var size int
for size < 32 && num != 0 { num *= 2 s.WriteString(strconv.Itoa(int(num))) num = num - float64(int(num)) size++ } if size < 32 { return s.String() } return"ERROR" }
funccountTriplets(nums []int)int { m := len(nums) tmp := make(map[int]int) for i := 0; i < m; i++ { for j := 0; j < m; j++ { tmp[nums[i]&nums[j]]++ } } var res int for i := 0; i < m; i++ { for k, v := range tmp { if nums[i]&k == 0 { res += v } } }
funcbraceExpansionII(expression string) []string { s := map[string]struct{}{} var dfs func(string) dfs = func(exp string) { // 找到第一个反括号 j := strings.Index(exp, "}") // 没有找到反括号,说明是单独的字符串,放到map中去重 if j == -1 { s[exp] = struct{}{} return } // 找到第一个反括号前面的第一个括号,这两者中间就是子问题 i := strings.LastIndex(exp[:j], "{") // 将括号前面+便利的子问题+反括号后,作为新的字符串,进行递归处理 a, c := exp[:i], exp[j+1:] for _, b := range strings.Split(exp[i+1:j], ",") { dfs(a + b + c) } } dfs(expression) // 将map中的字符串放到切片中,并且排序 ans := make([]string, 0, len(s)) for k := range s { ans = append(ans, k) } sort.Strings(ans) return ans }
funcminimumRecolors(blocks string, k int)int { size, res := 0, k for i := 0; i < k; i++ { if blocks[i] == 'W' { size++ } } if size < res { res = size }
for i := k; i < len(blocks); i++ { if blocks[i] == 'W' { size++ } if blocks[i-k] == 'W' { size-- } if size < res { res = size } } return res }
funcminSubarray(nums []int, p int)int { var sum int for i := 0; i < len(nums); i++ { sum += nums[i] } rem := sum % p
if rem == 0 { return0 }
res := len(nums) // (y+x) % p = rem // x = (p+rem - y ) % p allRem := map[int]int{0: -1} sum = 0 for i := 0; i < len(nums); i++ { sum += nums[i] tmpRem := sum % p last := (tmpRem + p - rem) % p if v, ok := allRem[last]; ok { temRes := i - v if temRes < res { res = temRes } } allRem[tmpRem] = i }
funcfindLongestSubarray(array []string) []string { all := map[int]int{0: -1}
var num, max int var res []string for i := 0; i < len(array); i++ { if unicode.IsLetter(rune(array[i][0])) { num++ } else { num-- } if v, ok := all[num]; ok { tmp := i - v if tmp > max { max = tmp res = array[v+1 : i+1] } } else { all[num] = i } }
funccountSubgraphsForEachDiameter(n int, edges [][]int) []int { // 建树,m代表城市编号,n是这个城市连接的编号,用于后面求解最长路径时快速便利 g := make([][]int, n) for _, e := range edges { x, y := e[0]-1, e[1]-1// 编号改为从 0 开始 g[x] = append(g[x], y) g[y] = append(g[y], x) }
// inSet保存要遍历的城市的个数 // vis保存便利的时候已经遍历过的城市,不会出现反过头成环 var inSet, vis [15]bool
// dfs 求树的直径,使用递归dfs,返回对应节点x的最深深度,调用时,需要重置diameter var dfs func(int)int dfs = func(x int) (maxLen int) { vis[x] = true for _, y := range g[x] { if !vis[y] && inSet[y] { ml := dfs(y) + 1 if ml > maxLen { maxLen = ml } } } return }
ans := make([]int, n-1) // 方法1:递归选择城市 //var f func(int) //f = func(i int) { // if i == n { // for v, b := range inSet { // if b { // vis, diameter = [15]bool{}, 0 // dfs(v) // break // } // } // if diameter > 0 && vis == inSet { // ans[diameter-1]++ // } // return // } // // // 不选城市 i // // inSet[i] = false 其实不选城市设置为false放在这里,理解起来会更加简单 // f(i + 1) // // // 选城市 i // inSet[i] = true // f(i + 1) // inSet[i] = false // 恢复现场,这里很重要,但是理解起来有点吃力,想等于在不选城市时,inSet[i] = false //} //f(0)
// 方法2:使用二进制,选择城市 for i := 0; i < 1<<n; i++ { var count int inSet = [15]bool{} for j := 0; j < n; j++ { if (i>>j)&1 == 1 { inSet[j] = true count++ } }
// 最起码有两个城市,才计算距离 if count > 1 { // 通过for循环每一个城市,确定直径
// 初始化最大距离 var diameter int for j := 0; j < n; j++ { if inSet[j] { // 初始化便利过的节点 vis = [15]bool{} tmp := dfs(j) if tmp > diameter && vis == inSet { diameter = tmp } } }
// 要确保所有节点都便利到,因此vis需要等于inSet if diameter > 0 { ans[diameter-1]++ } } } return ans }
funcmax(a, b int)int { if a < b { return b } return a }
2023年03月13日
2383. 赢得比赛需要的最少训练时长
解法1:依次计算需要战胜对手时,需要的经历和经验即可。也就是说,可以在中途回过头去训练。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
funcminNumberOfHours(initialEnergy int, initialExperience int, energy []int, experience []int)int { var res int for i := 0; i < len(energy); i++ { initialEnergy = initialEnergy - energy[i] if initialEnergy < 1 { res = res - initialEnergy + 1 initialEnergy = 1 } if initialExperience <= experience[i] { res = res + experience[i] - initialExperience + 1 initialExperience = experience[i] + 1 } initialExperience += experience[i] } return res }
funccountSubarrays(nums []int, k int)int { var flag int for i := 0; i < len(nums); i++ { if nums[i] == k { flag = i break } }
count := make(map[int]int) // 计数器 // 保留一个等于自身的值 count[0] = 1 var res,c int for i := 0; i < len(nums); i++ { c += getCount(nums[i],k) if i < flag { count[c]++ } else { // 结果为0,代表是相加是奇数的情况 p0 := count[c] // 等于对应数可以 p1 := count[c-1] // 等于对应数-1也可以 res += p0+p1 } } return res }
funcgetCount(i int,k int)int { if i > k { return1 } elseif i < k { return-1 } return0 }
funcanswerQueries(nums []int, queries []int) []int { sort.Ints(nums) all := make([]int, len(nums)) var sum int for i := 0; i < len(nums); i++ { sum += nums[i] all[i] = sum }
res := make([]int, len(queries)) for i := 0; i < len(queries); i++ { res[i] = sort.SearchInts(all, queries[i]+1) }
// Search uses binary search to find and return the smallest index i // in [0, n) at which f(i) is true, assuming that on the range [0, n), // f(i) == true implies f(i+1) == true. That is, Search requires that // f is false for some (possibly empty) prefix of the input range [0, n) // and then true for the (possibly empty) remainder; Search returns // the first true index. If there is no such index, Search returns n. // (Note that the "not found" return value is not -1 as in, for instance, // strings.Index.) // Search calls f(i) only for i in the range [0, n). // // A common use of Search is to find the index i for a value x in // a sorted, indexable data structure such as an array or slice. // In this case, the argument f, typically a closure, captures the value // to be searched for, and how the data structure is indexed and // ordered. // // For instance, given a slice data sorted in ascending order, // the call Search(len(data), func(i int) bool { return data[i] >= 23 }) // returns the smallest index i such that data[i] >= 23. If the caller // wants to find whether 23 is in the slice, it must test data[i] == 23 // separately. // // Searching data sorted in descending order would use the <= // operator instead of the >= operator. // // To complete the example above, the following code tries to find the value // x in an integer slice data sorted in ascending order: // // x := 23 // i := sort.Search(len(data), func(i int) bool { return data[i] >= x }) // if i < len(data) && data[i] == x { // // x is present at data[i] // } else { // // x is not present in data, // // but i is the index where it would be inserted. // } // // As a more whimsical example, this program guesses your number: // // func GuessingGame() { // var s string // fmt.Printf("Pick an integer from 0 to 100.\n") // answer := sort.Search(100, func(i int) bool { // fmt.Printf("Is your number <= %d? ", i) // fmt.Scanf("%s", &s) // return s != "" && s[0] == 'y' // }) // fmt.Printf("Your number is %d.\n", answer) // } funcSearch(n int, f func(int)bool) int { // Define f(-1) == false and f(n) == true. // Invariant: f(i-1) == false, f(j) == true. i, j := 0, n for i < j { h := int(uint(i+j) >> 1) // avoid overflow when computing h // i ≤ h < j if !f(h) { i = h + 1// preserves f(i-1) == false } else { j = h // preserves f(j) == true } } // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. return i }
1 2 3 4 5 6 7
// SearchInts searches for x in a sorted slice of ints and returns the index // as specified by Search. The return value is the index to insert x if x is // not present (it could be len(a)). // The slice must be sorted in ascending order. funcSearchInts(a []int, x int)int { return Search(len(a), func(i int)bool { return a[i] >= x }) }
funcfindLexSmallestString(s string, a int, b int)string { all := map[string]bool{s: true} stack := []string{s} res := s forlen(stack) > 0 { // 出栈 s = stack[0] stack = stack[1:] // 比较 if s < res { res = s }
// 转换 ss := []byte(s) s = s[len(s)-b:] + s[:len(s)-b] if !all[s] { all[s] = true stack = append(stack,s) } // 累加 for i := 1; i < len(ss); i += 2 { ss[i] = byte((int(ss[i]-'0')+a)%10) + '0' } if !all[string(ss)] { all[string(ss)] = true stack = append(stack,string(ss)) } } return res }
funcnumDupDigitsAtMostN(n int) (ans int) { s := strconv.Itoa(n) m := len(s) // 记录没有填过的数字的使用次数,用于提升便利速度 // 例如 如果计算了 12***,那么就不需要计算21***的数量 all := make([][1 << 10]int, m) for i := 0; i < m; i++ { for j := 0; j < 1<<10; j++ { // 将-1记录为没有使用过 all[i][j] = -1 } }
// 分别代表第几位,已经填过的数字,是否有限制,前缀是否是0 var f func(i int, mask int, limit bool, zero bool)int f = func(i int, mask int, limit bool, zero bool) (res int) { // 位数结束,代表该数字可以 if i == m { return1 }
// 自身没有限制,并且前缀不是0 if !limit && !zero { p := &all[i][mask] if *p > 0 { return *p } deferfunc() { *p = res }() }
// 先处理前面都是0的情况 if zero { // 此时i+1位不限制,并且前面都是0 res += f(i+1, 0, false, true) }
// 起始值 start := 0 if zero { start = 1 }
// 结束值 end := 9 if limit { end = int(s[i] - '0') } //fmt.Println(start,end) for ; start <= end; start++ { if mask>>start&1 != 1 { res += f(i+1, mask|1<<start, limit && start == end, false) } } return }
funcfindLengthOfShortestSubarray(arr []int)int { m := len(arr) // 右边 right := m - 1 for right > 0 && arr[right] >= arr[right-1] { right-- } if right == 0 { return0 } res := right // 左边 for i := 0; i < right; i++ { if i > 0 && arr[i] < arr[i-1] { break } for right < m && arr[i] > arr[right] { right++ } res = min(res, right-i-1) } return res }
funcmin(a, b int)int { if a > b { return b } return a }
2023年03月26日
2395. 和相等的子数组
解法1:使用HashMap并且遍历即可
1 2 3 4 5 6 7 8 9 10 11 12 13
funcfindSubarrays(nums []int)bool { m := len(nums) all := make(map[int]bool, m) for i := 0; i < m-1; i++ { tmp := nums[i] + nums[i+1] if all[tmp] { returntrue } else { all[tmp] = true } } returnfalse }
funcshortestCommonSupersequence(str1 string, str2 string)string { m, n := len(str1), len(str2) dp := make([][]int, m+1) dp[0] = make([]int, n+1) for i := 1; i <= m; i++ { dp[i] = make([]int, n+1) for j := 1; j <= n; j++ { if str1[i-1] == str2[j-1] { dp[i][j] = dp[i-1][j-1] + 1 } else { dp[i][j] = max(dp[i-1][j], dp[i][j-1]) } } } //fmt.Println(dp)
var ans strings.Builder i, j := m-1, n-1 for i >= 0 && j >= 0 { if str1[i] == str2[j] { ans.WriteByte(str1[i]) i-- j-- } else { if dp[i][j+1] > dp[i+1][j] { ans.WriteByte(str1[i]) i-- } else { ans.WriteByte(str2[j]) j-- } } }
for ;i >= 0;i-- { ans.WriteByte(str1[i]) } for ;j >= 0;j-- { ans.WriteByte(str2[j]) } str := ans.String() return reverseString(str) }
funcmax(i int, i2 int)int { if i > i2 { return i } return i2 }
funcreverseString(s string)string { var ans strings.Builder for i := len(s) - 1; i >= 0; i-- { ans.WriteByte(s[i]) } return ans.String() }
2023年03月29日
1641. 统计字典序元音字符串的数目
解法1:按照题目描述,其实有以下关系
1 2 3 4 5
f(n) a = f(n-1) a + f(n-1) e + f(n-1) i + f(n-1) o + f(n-1) u f(n) e = f(n-1) e + f(n-1) i + f(n-1) o + f(n-1) u f(n) i = f(n-1) i + f(n-1) o + f(n-1) u f(n) o = f(n-1) o + f(n-1) u f(n) u = f(n-1) u