小于等于 K 的最长二进制子序列
给你一个二进制字符串 s 和一个正整数 k 。
请你返回 s 的 最长 子序列,且该子序列对应的 二进制 数字小于等于 k 。
注意:
- 子序列可以有 前导 0 。
- 空字符串视为
0。 - 子序列 是指从一个字符串中删除零个或者多个字符后,不改变顺序得到的剩余字符序列。
示例 1:
输入: s = "1001010", k = 5
输出: 5
解释: s 中小于等于 5 的最长子序列是 "00010" ,对应的十进制数字是 2 。
注意 "00100" 和 "00101" 也是可行的最长子序列,十进制分别对应 4 和 5 。
最长子序列的长度为 5 ,所以返回 5 。
示例 2:
输入: s = "00101001", k = 1
输出: 6
解释: "000001" 是 s 中小于等于 1 的最长子序列,对应的十进制数字是 1 。
最长子序列的长度为 6 ,所以返回 6 。
提示:
1 <= s.length <= 1000s[i]要么是'0',要么是'1'。1 <= k <= 10^9
解析
一个思路是先把0都提取出来,再从后向前,看看哪里可以放1,不过这样实现起来很复杂,比赛的时候一直也没写出来。 后来,老婆看了看题目,一分钟就给出来了精妙的解法。
直接从左到右看 如果k是1,就数出所有的0,再看看最后一位是不是1就行了 从左到右,用字符串p记录当前可用字符串,每一次都给p追加上当前位置的字符,看看对应二进制是否大于k,没大,保留,继续加,大了,就把坐左边的1给扔了,over。
这个方法太巧妙了,长度直增不减到最后就最大了。
class Solution:
def remove_left_1(self, p):
p = list(p)
index = p.index("1")
p.pop(index)
return "".join(p)
def longestSubsequence(self, s: str, k: int) -> int:
if k == 1:
count_0 = s.count("0")
if s[-1] == "1":
res = count_0 + 1
else:
res = count_0
return res
p = ""
for index, v in enumerate(s):
p += v
if int(p, 2) <= k:
continue
else:
p = self.remove_left_1(p)
print(len(p), p)
return len(p)
作者:fei-xiang-de-cheng-zi
链接:https://leetcode.cn/problems/longest-binary-subsequence-less-than-or-equal-to-k/solution/ke-neng-shi-zui-jian-dan-de-by-fei-xiang-yrr5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在执行速度上也非常快,如果把pop操作也给好好优化一下,近似于O(N)了