github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/leetcode.go (about) 1 package util 2 3 import ( 4 "math" 5 ) 6 7 // Max for int 8 func Max(a, b int) int { 9 if a > b { 10 return a 11 } 12 13 return b 14 } 15 16 // Min for int 17 func Min(a, b int) int { 18 if a > b { 19 return b 20 } 21 22 return a 23 } 24 25 // MaxLengthOfUniqueSubstring returns the max length of unique sub string 26 func MaxLengthOfUniqueSubstring(s string) (l int) { 27 28 var indexes [math.MaxUint8] /*byte是uint8*/ int 29 n := len(s) 30 31 var i, j int 32 // 基于的观察: 33 // 如果s[j]跟[i,j)有重复j',那么可以跳过[i,j']的元素,i直接变为j'+1 34 for ; j < n; j++ { 35 byteJ := s[j] 36 // 假如indexes的元素非0,那么必定是这个byte上一次出现的位置j'+1 37 // 且j'的位置必须在[i,j)之间才有效 38 if indexes[byteJ] != 0 && indexes[byteJ] > i { 39 i = indexes[byteJ] 40 } 41 42 l = Max(l, j-i+1) 43 indexes[byteJ] = j + 1 44 } 45 return 46 } 47 48 // ManacherFallback when all byte values are used in s 49 func ManacherFallback(s string) (ss string) { 50 n := len(s) 51 52 for i := 0; i < n; i++ { 53 // 奇数的情况 54 j := 1 55 for ; i-j >= 0 && i+j < n; j++ { 56 if s[i-j] != s[i+j] { 57 break 58 } 59 } 60 if len(ss) < (j*2 - 1) { 61 ss = s[i-j+1 : i+j] 62 } 63 // 偶数的情况 64 if i+1 < n && s[i] == s[i+1] { 65 j := 1 66 for ; i-j >= 0 && i+1+j < n; j++ { 67 if s[i-j] != s[i+1+j] { 68 break 69 } 70 } 71 if len(ss) < j*2 { 72 ss = s[i-j+1 : i+j+1] 73 } 74 } 75 } 76 return 77 } 78 79 // ManacherWithFallback tries Manacher if possible 80 func ManacherWithFallback(s string) (ss string) { 81 var indexes [math.MaxUint8] /*byte是uint8*/ bool 82 n := len(s) 83 for i := 0; i < n; i++ { 84 indexes[s[i]] = true 85 } 86 canManacher := false 87 var manacherByte byte 88 for i, exists := range indexes { 89 if !exists { 90 canManacher = true 91 manacherByte = byte(i) 92 break 93 } 94 } 95 if !canManacher { 96 ss = ManacherFallback(s) 97 return 98 } 99 100 // preprocess 101 bytes := make([]byte, 2*n+1, 2*n+1) 102 bytes[0] = manacherByte 103 for i := 0; i < n; i++ { 104 bytes[2*i+1] = s[i] 105 bytes[2*i+2] = manacherByte 106 } 107 108 r := make([]int, 2*n+1) 109 var maxRightPos, maxRight, maxRPos, maxR int 110 r[0] = 1 111 r[2*n] = 1 112 for i := 1; i < 2*n; i++ { 113 if i >= maxRight { 114 // 半径包括自己,所以1是最小值 115 r[i] = 1 116 } else { 117 // i在maxRight以内 118 // j'坐标为2*maxRightPos-i 119 r[i] = Min(maxRight-i, r[2*maxRightPos-i]) 120 } 121 // 尝试扩大半径 122 for { 123 if i-r[i] >= 0 && i+r[i] <= 2*n && bytes[i-r[i]] == bytes[i+r[i]] { 124 r[i]++ 125 } else { 126 break 127 } 128 } 129 if i+r[i]-1 > maxRight { 130 maxRight = i + r[i] - 1 131 maxRightPos = i 132 } 133 if maxR < r[i] { 134 maxRPos = i 135 maxR = r[i] 136 } 137 } 138 139 targetBytes := make([]byte, 0, r[maxRPos]-1 /*最终结果的长度*/) 140 for i := maxRPos - r[maxRPos] + 1; i < maxRPos+r[maxRPos]; i++ { 141 if bytes[i] != manacherByte { 142 targetBytes = append(targetBytes, bytes[i]) 143 } 144 } 145 146 ss = String(targetBytes) 147 if len(ss) != r[maxRPos]-1 { 148 panic("size != r[maxRPos]-1") 149 } 150 151 return 152 } 153 154 // ReverseDigits for reverse digits 155 func ReverseDigits(n int32) (r int32) { 156 157 if n > 0 { 158 for n != 0 { 159 pop := n % 10 160 // 溢出判断 161 if (r > math.MaxInt32/10) || (r == math.MaxInt32/10 && pop > 7) { 162 // 上溢出 163 return 0 164 } 165 166 r = 10*r + pop 167 n /= 10 168 } 169 } else { 170 for n != 0 { 171 pop := n % 10 172 // 溢出判断 173 if r < math.MinInt32/10 || (r == math.MinInt32/10 && pop < -8) { 174 // 下溢出 175 return 0 176 } 177 178 r = 10*r + pop 179 n /= 10 180 } 181 } 182 183 return 184 } 185 186 // IsPalindrome checks whether n is palindrome 187 func IsPalindrome(n int) bool { 188 if n < 0 { 189 return false 190 } 191 192 var reverted int 193 // 反转一半即可 194 for n > reverted { 195 reverted = 10*reverted + n%10 196 n /= 10 197 } 198 199 return reverted == n || reverted/10 == n 200 } 201 202 // PatternMatchAllTD matches p against the whole s 203 // pattern supprts . and * 204 // top down 205 func PatternMatchAllTD(s, p string) bool { 206 207 slen := len(s) 208 plen := len(p) 209 if plen == 0 { 210 return slen == 0 211 } 212 213 memo := make([][]*bool, slen) 214 for i := 0; i < slen; i++ { 215 memo[i] = make([]*bool, plen) 216 } 217 218 var subProbFunc func(i, j int) bool 219 // 子问题函数 220 subProbFunc = func(i, j int) bool { 221 222 // 如果都越界,匹配成功 223 if i >= slen && j >= plen { 224 return true 225 } 226 // 只有p越界,匹配失败 227 if j >= plen { 228 return false 229 } 230 // i越界,p未越界 231 if i >= slen { 232 // 看p能否匹配空 233 if j+1 >= plen { 234 return false 235 } 236 if p[j+1] != '*' { 237 return false 238 } 239 return subProbFunc(i, j+2) 240 } 241 242 // 如果已计算,直接返回结果 243 if memo[i][j] != nil { 244 return *memo[i][j] 245 } 246 247 match := s[i] == p[j] || p[j] == '.' 248 if j+1 >= plen { 249 result := match && i == slen-1 250 memo[i][j] = &result 251 return result 252 } 253 254 // 转移方程 255 256 if p[j+1] == '*' { 257 result := subProbFunc(i, j+2) || // 匹配0次 258 (match && subProbFunc(i+1, j+2)) || // 匹配1次 259 (match && subProbFunc(i+1, j)) // 匹配多次 260 261 memo[i][j] = &result 262 return result 263 } 264 265 result := match && subProbFunc(i+1, j+1) 266 memo[i][j] = &result 267 268 return result 269 } 270 271 return subProbFunc(0, 0) 272 } 273 274 // PatternMatchAllBU matches p against the whole s 275 // pattern supprts . and * 276 // bottom up 277 func PatternMatchAllBU(s, p string) bool { 278 279 slen := len(s) 280 plen := len(p) 281 if plen == 0 { 282 return slen == 0 283 } 284 285 memo := make([][]*bool, slen) 286 for i := 0; i < slen; i++ { 287 memo[i] = make([]*bool, plen) 288 } 289 290 var subProbFunc func(i, j int) bool 291 subProbFunc = func(i, j int) bool { 292 if i < 0 && j < 0 { 293 return true 294 } 295 if j < 0 { 296 return false 297 } 298 if i < 0 { 299 // 看p能否匹配空 300 if p[j] != '*' { 301 return false 302 } 303 if j == 0 { 304 return false 305 } 306 return subProbFunc(i, j-2) 307 } 308 309 // 如果已计算,直接返回结果 310 if memo[i][j] != nil { 311 return *memo[i][j] 312 } 313 314 match := s[i] == p[j] || p[j] == '.' 315 if j == 0 { 316 result := match && i == 0 317 memo[i][j] = &result 318 return result 319 } 320 321 if p[j] == '*' { 322 result := subProbFunc(i, j-2) || /*匹配0次*/ 323 ((p[j-1] == s[i] || p[j-1] == '.') && 324 (subProbFunc(i-1, j-2) || /*匹配1次*/ 325 subProbFunc(i-1, j))) /*匹配多次*/ 326 memo[i][j] = &result 327 return result 328 } 329 330 result := match && subProbFunc(i-1, j-1) 331 memo[i][j] = &result 332 return result 333 } 334 335 return subProbFunc(slen-1, plen-1) 336 } 337 338 // PatternMatchAllRec is the recursive version for PatternMatchAll 339 func PatternMatchAllRec(s, p string) bool { 340 if len(p) == 0 { 341 return len(s) == 0 342 } 343 344 if len(s) == 0 { 345 // p必须是x*y*这种 346 if len(p) < 2 || p[1] != '*' { 347 return false 348 } 349 return PatternMatchAllRec(s, p[2:]) 350 } 351 352 match := s[0] == p[0] || p[0] == '.' 353 if len(p) < 2 { 354 return match && len(s) == 1 355 } 356 357 if p[1] == '*' { 358 return PatternMatchAllRec(s, p[2:]) /*匹配0次*/ || 359 (match && PatternMatchAllRec(s[1:], p[2:])) /*匹配1次*/ || 360 (match && PatternMatchAllRec(s[1:], p)) /*匹配多次*/ 361 } 362 363 return match && PatternMatchAllRec(s[1:], p[1:]) 364 365 } 366 367 // FindOnceNum find the number that appears only once 368 // caller should make sure only one num appears once 369 func FindOnceNum(nums []int) (r int) { 370 for _, n := range nums { 371 r ^= n 372 } 373 return 374 } 375 376 // MinCoveringSubstr finds min substr of s that covers t 377 func MinCoveringSubstr(s, t string) (ss string) { 378 379 // 双指针滑动窗口 380 var left, right, matched int 381 382 needed := make(map[byte]int) 383 for i := 0; i < len(t); i++ { 384 needed[t[i]]++ 385 } 386 windowed := make(map[byte]int) 387 minLen := len(s) + 1 388 389 for right < len(s) { 390 391 rb := s[right] 392 if _, ok := needed[rb]; ok { 393 windowed[rb]++ 394 if windowed[rb] == needed[rb] { 395 matched++ 396 } 397 } 398 399 if matched == len(needed) { 400 for { 401 lb := s[left] 402 if _, ok := needed[lb]; !ok { 403 left++ 404 continue 405 } 406 if windowed[lb] > needed[lb] { 407 left++ 408 windowed[lb]-- 409 continue 410 } 411 // left不能再右了 412 if right-left+1 < minLen { 413 ss = s[left : right+1] 414 minLen = right - left + 1 415 } 416 left++ 417 windowed[lb]-- 418 matched-- 419 break 420 } 421 } 422 423 right++ 424 } 425 426 return 427 } 428 429 // LongestConsecutive finds longest consecutive in nums 430 func LongestConsecutive(nums []int) (sn, length int) { 431 numMap := make(map[int]struct{}) 432 for _, n := range nums { 433 numMap[n] = struct{}{} 434 } 435 436 for _, n := range nums { 437 if _, ok := numMap[n-1]; ok { 438 continue 439 } 440 nn := n + 1 441 for { 442 if _, ok := numMap[nn]; ok { 443 nn++ 444 } else { 445 if nn-n > length { 446 length = nn - n 447 sn = n 448 } 449 break 450 } 451 } 452 } 453 454 return 455 }