注册了比赛,被叫出去跟朋友喝酒了。幸亏这场没玩,要不要降分了,这几天喝酒喝的脑袋傻了,今天才补下这套题。调整下状态,准备回京务工了。
1. Add to Array-Form of Integer
解题思路:模拟下高精度加法即可。
实现代码:
func maxInt(a, b int) int {
if a > b {
return a
}
return b
}
func reverseArr(a []int) {
if len(a) == 0 {
return
}
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
}
func addToArrayForm(A []int, K int) []int {
reverseArr(A)
B := []int{}
for K > 0 {
B = append(B, K%10)
K /= 10
}
C := make([]int, maxInt(len(A), len(B)))
var a, b, c int
for i := 0; i < len(C); i++ {
a = 0
if i < len(A) {
a = A[i]
}
b = 0
if i < len(B) {
b = B[i]
}
C[i] = (a + b + c) % 10
c = (a + b + c) / 10
}
if c > 0 {
C = append(C, c)
}
reverseArr(C)
return C
}
2. Satisfiability of Equality Equations
解题思路:由于相等关系具有传递性,因此我们可以利用并查集维护相等关系的集合。对于 a != b
的情况, 如果 a
和 b
原先是相等的, 则表示存在矛盾条件.
实现代码:
func initSet(p []int) {
for i := range p {
p[i] = -1
}
}
func findSet(x int, p []int) int {
if p[x] < 0 {
return x
}
p[x] = findSet(p[x], p)
return p[x]
}
func unionSet(x, y int, p []int) bool {
p1 := findSet(x, p)
p2 := findSet(y, p)
if p1 == p2 {
return true
}
p[p1] += p[p2]
p[p2] = p1
return false
}
func equationsPossible(equations []string) bool {
if len(equations) == 0 {
return true
}
p := make([]int, 40)
initSet(p)
for i := range equations {
if equations[i][1] == '=' {
unionSet(int(equations[i][0]-'a'), int(equations[i][3]-'a'), p)
}
}
for i := range equations {
if equations[i][1] == '!' {
if findSet(int(equations[i][0]-'a'), p) == findSet(int(equations[i][3]-'a'), p) {
return false
}
}
}
return true
}
3. Broken Calculator
解题思路: 不要写 bfs 肯定挂, 这题需要贪心来搞. 具体可以参考这篇文章 https://leetcode.com/articles/broken-calculator/
实现代码:
func brokenCalc(X int, Y int) int {
if X >= Y {
return X - Y
}
ans := 0
for Y > X {
if Y%2 == 0 {
Y /= 2
} else {
Y++
}
ans++
}
return ans + X - Y
}
4. Subarrays with K Different Integers
解题思路: 求解对于每一个位置 i
以 A[i]
为结尾的不同数字恰好为 K
的方案数, 则总的方案数为 SUM(i)
. 对于每个位置 i
, 存在 k
属于某个区间[l,r]
使得 Ak ... Ai
恰好存在 K
个不同的数字; 另外对于 j > i
, 则其对应的区间[lj, rj]
与[li, ri]
存在如下关系: li <= lj && ri <= rj && lj <= rj
,因为[i+1, j]
区间内可能引入了新的元素嘛。由此可以 l
和 r
随着 i
的增大是单调递增的。因此,每次加入新的元素 A[i]
,只需要动态调整下 [li, ri]
即可,总的复杂度为O(N)
.
实现代码:
type Stat struct {
cnt int
cmap map[int]int
}
func NewStat() *Stat {
return &Stat{
cnt: 0,
cmap: map[int]int{},
}
}
func (st *Stat) Add(x int) {
if _, ok := st.cmap[x]; !ok {
st.cmap[x] = 1
st.cnt++
return
}
st.cmap[x]++
}
func (st *Stat) Del(x int) {
if _, ok := st.cmap[x]; !ok {
return
}
st.cmap[x]--
if st.cmap[x] == 0 {
delete(st.cmap, x)
st.cnt--
}
}
func (st *Stat) Count() int {
return st.cnt
}
func subarraysWithKDistinct(A []int, K int) int {
if len(A) == 0 {
return 0
}
var (
res int
l int
r int
st1 = NewStat()
st2 = NewStat()
)
l, r = 0, 0
for i := range A {
st1.Add(A[i])
st2.Add(A[i])
for st1.Count() > K {
st1.Del(A[l])
l++
}
for st2.Count() >= K {
st2.Del(A[r])
r++
}
res += r - l
}
return res
}