只通过了30%的用例,我心态很崩啊...
1264
2022.05.04
发布于 未知归属地

简介

对于一个二进制字符串,已知有以下变换规则:

  1. 00 -> 10

  2. 10 -> 01
    输入一个字符串,可以进行任意次变换,求最后最大的二进制串是多少
    例如:

  3. 输入:10
    输出:10

  4. 输入:00
    输出:10

  5. 输入:0101
    输出:1011


代码


func Replace(s string) string {
	b := []byte(s)
	replace(b)
	return string(b)
}

func replace(b []byte) {
	l, r, zp := 0, len(b)-1, -1
	for l < r {
		// 最左边是1就不用看了,不管怎么变,对于当前位就是最好的了
		for ; l <= r && b[l] == '1'; l++ {
		}

		// 最右边是1就不用看了,没有对应的规则
		for ; r >= l && b[r] == '1'; r-- {
		}

		// 当前r是0,但是到l之间仍有距离,且r的前一位也是1,这时可以变换 10 为 01,为下面凑 00
		for ; r-1 > l && b[r-1] == '1'; r-- {
			b[r-1], b[r] = '0', '1'
		}

		// 此时,l 应该指向的是从左至右第一个0,r 应该指向的是从右至左第一个0,如果两个相遇了,那就说明没有变化的余地了
		if l >= r {
			return
		}

		if b[l+1] == '0' {
			// 这种情况就是 '00',可以变换为 '10'
			b[l], b[l+1] = '1', '0'
			l++
			continue
		}

		// 这种情况就是 '01',找 01..10这样的结构,可以直接变化为 101..1
		if zp == -1 {
			zp = l + 2
		}

		for ; zp <= r && b[zp] == '1'; zp++ {
		}

		if zp > r {
			// 找到最右侧,也没发现0
			return
		}

		b[l], b[l+1], b[zp] = '1', '0', '1'

		// 现在又是10结构了,下标右移再判断即可
		l++
		zp++
	}
}

有没有大佬给我看看对不对呢?

评论 (7)