diff --git a/problems/binary-string-with-substrings-representing-1-to-n/binary_string_with_substrings_representing_1_to_n.go b/problems/binary-string-with-substrings-representing-1-to-n/binary_string_with_substrings_representing_1_to_n.go new file mode 100644 index 000000000..b4a4f651b --- /dev/null +++ b/problems/binary-string-with-substrings-representing-1-to-n/binary_string_with_substrings_representing_1_to_n.go @@ -0,0 +1,33 @@ +package binary_string_with_substrings_representing_1_to_n + +import "strings" + +func queryString(S string, N int) bool { + end := N >> 1 + for N >= end { + if !strings.Contains(S, binaryString(N)) { + return false + } + N-- + } + return true +} + +func binaryString(n int) string { + B := make([]byte, 0, 30) + for n > 0 { + B = append(B, byte(n&1)+'0') + n >>= 1 + } + swap(B) + return string(B) +} + +func swap(B []byte) { + i, j := 0, len(B)-1 + for i < j { + B[i], B[j] = B[j], B[i] + i++ + j-- + } +} diff --git a/problems/defanging-an-ip-address/defanging_an_ip_address.go b/problems/defanging-an-ip-address/defanging_an_ip_address.go new file mode 100644 index 000000000..a5052c794 --- /dev/null +++ b/problems/defanging-an-ip-address/defanging_an_ip_address.go @@ -0,0 +1,7 @@ +package defanging_an_ip_address + +import "strings" + +func defangIPaddr(address string) string { + return strings.Replace(address, ".", "[.]", -1) +} diff --git a/problems/distant-barcodes/distant_barcodes.go b/problems/distant-barcodes/distant_barcodes.go new file mode 100644 index 000000000..20f72091b --- /dev/null +++ b/problems/distant-barcodes/distant_barcodes.go @@ -0,0 +1,31 @@ +package distant_barcodes + +import "sort" + +func rearrangeBarcodes(A []int) []int { + n := len(A) + + count := [10001]int{} + for _, a := range A { + count[a]++ + } + + sort.Slice(A, func(i int, j int) bool { + if count[A[i]] == count[A[j]] { + return A[i] < A[j] + } + return count[A[i]] > count[A[j]] + }) + + res := make([]int, n) + i := 0 + for _, a := range A { + res[i] = a + i += 2 + if i >= n { + i = 1 + } + } + + return res +} diff --git a/problems/flip-columns-for-maximum-number-of-equal-rows/flip_columns_for_maximum_number_of_equal_rows.go b/problems/flip-columns-for-maximum-number-of-equal-rows/flip_columns_for_maximum_number_of_equal_rows.go new file mode 100644 index 000000000..6c58b3c9e --- /dev/null +++ b/problems/flip-columns-for-maximum-number-of-equal-rows/flip_columns_for_maximum_number_of_equal_rows.go @@ -0,0 +1,31 @@ +package flip_columns_for_maximum_number_of_equal_rows + +import "strings" + +func maxEqualRowsAfterFlips(A [][]int) int { + count := make(map[string]int, 300) + var sb strings.Builder + for _, r := range A { + r0 := r[0] + for _, x := range r { + sb.WriteByte(byte(x ^ r0 + '0')) + } + count[sb.String()]++ + sb.Reset() + } + + res := 0 + + for _, c := range count { + res = max(res, c) + } + + return res +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/problems/greatest-common-divisor-of-strings/greatest_common_divisor_of_strings.go b/problems/greatest-common-divisor-of-strings/greatest_common_divisor_of_strings.go new file mode 100644 index 000000000..32e0dc95e --- /dev/null +++ b/problems/greatest-common-divisor-of-strings/greatest_common_divisor_of_strings.go @@ -0,0 +1,36 @@ +package greatest_common_divisor_of_strings + +import "strings" + +func gcdOfStrings(s1, s2 string) string { + l1, l2 := len(s1), len(s2) + d := gcd(max(l1, l2), min(l1, l2)) + p := s2[:d] + if s1 == strings.Repeat(p, l1/d) && + s2 == strings.Repeat(p, l2/d) { + return p + } + return "" +} + +// a >= b +func gcd(a, b int) int { + if b == 0 { + return a + } + return gcd(b, a%b) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/problems/largest-values-from-labels/largest_values_from_labels.go b/problems/largest-values-from-labels/largest_values_from_labels.go new file mode 100644 index 000000000..569844a5d --- /dev/null +++ b/problems/largest-values-from-labels/largest_values_from_labels.go @@ -0,0 +1,29 @@ +package largest_values_from_labels + +import "sort" + +func largestValsFromLabels(values []int, labels []int, num_wanted int, use_limit int) int { + for i, v := range values { + values[i] = v<<16 + labels[i] + } + + sort.Slice(values, func(i int, j int) bool { + return values[i] > values[j] + }) + + count := [20001]int{} + res := 0 + for _, v := range values { + if count[v&0xFFFF] == use_limit { + continue + } + res += v >> 16 + count[v&0xFFFF]++ + num_wanted-- + if num_wanted == 0 { + break + } + } + + return res +} diff --git a/problems/max-consecutive-ones-iii/max_consecutive_ones_iii.go b/problems/max-consecutive-ones-iii/max_consecutive_ones_iii.go index 6af7e2f55..9aed00c87 100644 --- a/problems/max-consecutive-ones-iii/max_consecutive_ones_iii.go +++ b/problems/max-consecutive-ones-iii/max_consecutive_ones_iii.go @@ -1,6 +1,5 @@ package max_consecutive_ones_iii -// ref: https://leetcode.com/problems/max-consecutive-ones-iii/discuss/247564/JavaC%2B%2BPython-Sliding-Window func longestOnes(A []int, K int) int { left, right := 0, 0 for right = range A { diff --git a/problems/moving-stones-until-consecutive-ii/moving_stones_until_consecutive_ii.go b/problems/moving-stones-until-consecutive-ii/moving_stones_until_consecutive_ii.go new file mode 100644 index 000000000..a6e34f5a5 --- /dev/null +++ b/problems/moving-stones-until-consecutive-ii/moving_stones_until_consecutive_ii.go @@ -0,0 +1,42 @@ +package moving_stones_until_consecutive_ii + +import "sort" + +func numMovesStonesII(stones []int) []int { + sort.Ints(stones) + return []int{low(stones), high(stones)} +} + +func high(s []int) int { + n := len(s) + return max(s[n-1]-s[1], s[n-2]-s[0]) - n + 2 +} + +func low(s []int) int { + n := len(s) + // corner case + if (s[n-2]-s[0] == n-2 && s[n-1]-s[n-2] > 2) || + (s[n-1]-s[1] == n-2 && s[1]-s[0] > 2) { + return 2 + } + // sliding window is s[i:j] + width, i, j := 0, 0, 1 + for ; j < n; j++ { + if s[j]-s[i] < n { + continue + } + width = max(width, j-i) + i = j + } + width = max(width, j-i) + // finally, all stone move into maxWidth windows + // so need move n-width stones + return n - width +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/problems/occurrences-after-bigram/occurrences_after_bigram.go b/problems/occurrences-after-bigram/occurrences_after_bigram.go new file mode 100644 index 000000000..2f8cd622c --- /dev/null +++ b/problems/occurrences-after-bigram/occurrences_after_bigram.go @@ -0,0 +1,16 @@ +package occurrences_after_bigram + +import "strings" + +func findOcurrences(text string, first string, second string) []string { + words := strings.Split(text, " ") + n := len(words) + res := make([]string, 0, n) + for i := 0; i+2 < n; i++ { + if words[i] == first && + words[i+1] == second { + res = append(res, words[i+2]) + } + } + return res +} diff --git a/problems/shortest-common-supersequence/shortest_common_supersequence.go b/problems/shortest-common-supersequence/shortest_common_supersequence.go new file mode 100644 index 000000000..0e51cf165 --- /dev/null +++ b/problems/shortest-common-supersequence/shortest_common_supersequence.go @@ -0,0 +1,64 @@ +package shortest_common_supersequence + +import "strings" + +func shortestCommonSupersequence(A, B string) string { + m, n := len(A), len(B) + // 解题思路, + // 先求出 A 和 B 的 LCS, + // 然后,在 LCS 上添加缺少的字母 + // 利用 dp 求解 LCS , + // dp[i][j]=k 表示 A[:i] 与 B[:j] 的 LCS 的长度为 k + // 在递归过程中,会出现三种情况: + // 1. A[i]=B[j], 则 dp[i][j]= dp[i-1][j-1]+1 + // 2. A[i]!=B[j] 且 dp[i-1][j] >= dp[i][j-1],则 dp[i][j]=dp[i-1][j] + // 3. A[i]!=B[j] 且 dp[i-1][j] < dp[i][j-1],则 dp[i][j]=dp[i][j+1] + + dp := [1001][1001]int{} + b := [1001][1001]int{} // 记录哪种情况发生了,以便添加字母 + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if A[i-1] == B[j-1] { + dp[i][j] = dp[i-1][j-1] + 1 + b[i][j] = 1 + } else if dp[i-1][j] >= dp[i][j-1] { + dp[i][j] = dp[i-1][j] + b[i][j] = 2 + } else { + dp[i][j] = dp[i][j-1] + b[i][j] = 3 + } + } + } + + var sb strings.Builder + var dfs func(int, int) + dfs = func(i, j int) { + if i == 0 { + sb.WriteString(B[:j]) + return + } + + if j == 0 { + sb.WriteString(A[:i]) + return + } + + switch b[i][j] { + case 1: + dfs(i-1, j-1) + sb.WriteByte(A[i-1]) + case 2: + dfs(i-1, j) + sb.WriteByte(A[i-1]) + case 3: + dfs(i, j-1) + sb.WriteByte(B[j-1]) + } + } + + dfs(m, n) + + return sb.String() +} diff --git a/problems/smallest-subsequence-of-distinct-characters/smallest_subsequence_of_distinct_characters.go b/problems/smallest-subsequence-of-distinct-characters/smallest_subsequence_of_distinct_characters.go new file mode 100644 index 000000000..3be815a67 --- /dev/null +++ b/problems/smallest-subsequence-of-distinct-characters/smallest_subsequence_of_distinct_characters.go @@ -0,0 +1,39 @@ +package smallest_subsequence_of_distinct_characters + +import "strings" + +func smallestSubsequence(S string) string { + n := len(S) + + last := [26]int{} + for i, c := range S { + last[c-'a'] = i + } + + stack, top := make([]int, n), -1 + hasSeen := [26]bool{} + for i := 0; i < n; i++ { + c := int(S[i] - 'a') + if hasSeen[c] { + continue + } + for top >= 0 && + stack[top] > c && + i < last[stack[top]] { + pop := stack[top] + top-- + hasSeen[pop] = false + } + top++ + stack[top] = c + hasSeen[c] = true + } + + var sb strings.Builder + for i := 0; i <= top; i++ { + b := byte(stack[i] + 'a') + sb.WriteByte(b) + } + + return sb.String() +} diff --git a/problems/statistics-from-a-large-sample/statistics_from_a_large_sample.go b/problems/statistics-from-a-large-sample/statistics_from_a_large_sample.go new file mode 100644 index 000000000..7e44f217e --- /dev/null +++ b/problems/statistics-from-a-large-sample/statistics_from_a_large_sample.go @@ -0,0 +1,86 @@ +package statistics_from_a_large_sample + +import "sort" + +func sampleStats(count []int) []float64 { + return []float64{ + minimum(count), + maximum(count), + mean(count), + median(count), + mode(count), + } +} + +// minimum:最小值 +func minimum(count []int) float64 { + i := 0 + for ; i < len(count); i++ { + if count[i] != 0 { + break + } + } + return float64(i) +} + +// maximum:最大值 +func maximum(count []int) float64 { + i := len(count) - 1 + for ; i >= 0; i-- { + if count[i] != 0 { + break + } + } + return float64(i) +} + +// mean :平均数 +func mean(count []int) float64 { + sum, c := 0, 0 + for i := 0; i < len(count); i++ { + if count[i] == 0 { + continue + } + sum += i * count[i] + c += count[i] + } + return float64(sum) / float64(c) +} + +// median :中位数,排序后,位于正中间的数。 +func median(count []int) float64 { + k := make([]int, 0, 256) + c := make([]int, 0, 256) + sum := 0 + for i := 0; i < len(count); i++ { + if count[i] == 0 { + continue + } + sum += count[i] + k = append(k, i) + c = append(c, sum) + } + if sum%2 == 1 { + h := sum/2 + 1 + i := sort.SearchInts(c, h) + return float64(k[i]) + } + h := sum / 2 + i := sort.SearchInts(c, h) + j := sort.SearchInts(c, h+1) + return float64(k[i]+k[j]) / 2 +} + +// mode :出现次数最多的数 +func mode(count []int) float64 { + k, c := -1, -1 + for i := 0; i < len(count); i++ { + if count[i] == 0 { + continue + } + if c < count[i] { + k, c = i, count[i] + } + } + return float64(k) +} diff --git a/problems/video-stitching/video_stitching.go b/problems/video-stitching/video_stitching.go new file mode 100644 index 000000000..2bbe00ce3 --- /dev/null +++ b/problems/video-stitching/video_stitching.go @@ -0,0 +1,31 @@ +package video_stitching + +import "sort" + +func videoStitching(clips [][]int, T int) int { + sort.Slice(clips, func(i int, j int) bool { + return clips[i][0] < clips[j][0] + }) + + res := 0 + + for i, start, end := 0, 0, 0; start < T; start = end { + for i < len(clips) && clips[i][0] <= start { + end = max(end, clips[i][1]) + i++ + } + if start == end { + return -1 + } + res++ + } + + return res +} + +func max(a, b int) int { + if a > b { + return a + } + return b +}