Небезынтересно выглядит реализация этого же подхода на Go
– у них весьма своеобразно реализуются итераторы в неожиданном для Go функциональном стиле. В реальной же практике такое редко гошники практикуют, как я понимаю, — гораздо проще байты строки in-place инвертировать.
// CharLockPair represents a character and its corresponding lock state.
type CharLockPair struct {
char, lock rune
}
// Seq defines a functional iterator for yielding elements of type T.
type Seq[T any] func(func(T) bool)
// canBeValid checks if the given string can be a valid parentheses string.
func canBeValid(s, locked string) bool {
if len(s)%2 != 0 {
return false
}
// Forward pass
if !checkBalance(forwardIter(s, locked)) {
return false
}
// Backward pass
if !checkBalance(backwardIter(s, locked)) {
return false
}
return true
}
// checkBalance processes the iterator and determines if the sequence is balanced.
func checkBalance(seq Seq[CharLockPair]) bool {
balance, free := 0, 0
for pair := range seq {
char, lock := pair.char, pair.lock
if lock == '0' {
free++
} else if char == '(' {
balance++
} else {
balance--
}
if balance < 0 {
if free == 0 {
return false // Stop iteration early
}
balance++
free--
}
}
return balance <= free
}
// forwardIter generates an iterator for the forward pass.
func forwardIter(s, locked string) Seq[CharLockPair] {
return func(yield func(CharLockPair) bool) {
for i := 0; i < len(s); i++ {
if !yield(CharLockPair{char: rune(s[i]), lock: rune(locked[i])}) {
return
}
}
}
}
// backwardIter generates an iterator for the backward pass with swapped characters.
func backwardIter(s, locked string) Seq[CharLockPair] {
return func(yield func(CharLockPair) bool) {
for i := len(s) - 1; i >= 0; i-- {
char := rune(s[i])
if char == '(' {
char = ')'
} else {
char = '('
}
if !yield(CharLockPair{char: char, lock: rune(locked[i])}) {
return
}
}
}
}
перейти
Ну и добавлю без объяснений более короткое решение, с использованием продвинутых битовых хаков, которое стоит попробовать осмыслить самостоятельно.
impl Solution {
pub fn minimize_xor(num1: i32, num2: i32) -> i32 {
let n1 = num1.count_ones();
let n2 = num2.count_ones();
let mut result = num1;
for _ in n1..n2 {
result |= result + 1
}
for _ in n2..n1 {
result &= result -1
}
result
}
}
перейти