85 lines
1.4 KiB
Go
85 lines
1.4 KiB
Go
// Package q761 implements a solution for https://leetcode.com/problems/special-binary-string/
|
|
package q761
|
|
|
|
func toNumber(arrs ...[]byte) int {
|
|
r := 0
|
|
for i := range arrs {
|
|
for _, num := range arrs[i] {
|
|
r = r<<1 + int(num)
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
|
|
func fromNumber(arr []byte, num int) {
|
|
for i := len(arr) - 1; i >= 0; i-- {
|
|
arr[i] = byte(num % 2)
|
|
num >>= 1
|
|
}
|
|
}
|
|
|
|
func move(arr []byte) int {
|
|
specials := [][2]int{}
|
|
specialsMap := make(map[int][]int, len(arr)+1)
|
|
val := toNumber(arr)
|
|
|
|
for i := range len(arr) - 1 {
|
|
if arr[i] == 0 {
|
|
continue
|
|
}
|
|
bal := 1
|
|
for j := i + 1; j < len(arr); j++ {
|
|
switch arr[j] {
|
|
case 0:
|
|
bal--
|
|
case 1:
|
|
bal++
|
|
}
|
|
|
|
if bal < 0 {
|
|
break
|
|
}
|
|
if bal == 0 {
|
|
specials = append(specials, [2]int{i, j})
|
|
specialsMap[i] = append(specialsMap[i], j)
|
|
}
|
|
}
|
|
}
|
|
|
|
for i := range specials {
|
|
l1, r1 := specials[i][0], specials[i][1]
|
|
l2 := r1 + 1
|
|
for _, r2 := range specialsMap[l2] {
|
|
swapped := toNumber(arr[:l1], arr[l2:r2+1], arr[l1:l2], arr[r2+1:])
|
|
if swapped > val {
|
|
val = swapped
|
|
}
|
|
}
|
|
}
|
|
return val
|
|
}
|
|
|
|
func makeLargestSpecial(s string) string {
|
|
arr := []byte(s)
|
|
for i := range arr {
|
|
arr[i] -= '0'
|
|
}
|
|
|
|
val := toNumber(arr)
|
|
for {
|
|
newVal := move(arr)
|
|
if newVal > val {
|
|
val = newVal
|
|
fromNumber(arr, newVal)
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
for i := range arr {
|
|
arr[i] += '0'
|
|
}
|
|
return string(arr)
|
|
}
|
|
|
|
var _ = makeLargestSpecial
|