初学python记录:力扣1702. 修改后的最大二进制字符串

题目:

给你一个二进制字符串 binary ,它仅有 0 或者 1 组成。你可以使用下面的操作任意次对它进行修改:

  • 操作 1 :如果二进制串包含子字符串 "00" ,你可以用 "10" 将其替换。
    • 比方说, "00010" -> "10010"
  • 操作 2 :如果二进制串包含子字符串 "10" ,你可以用 "01" 将其替换。
    • 比方说, "00010" -> "00001"

请你返回执行上述操作任意次以后能得到的 最大二进制字符串 。如果二进制字符串 x 对应的十进制数字大于二进制字符串 y 对应的十进制数字,那么我们称二进制字符串 x 大于二进制字符串 y 

思考:

操作1:“00” ----> “10”

操作2:“10” ----> “01”

那么对于任意二进制字符串来说,要使得变换后的值最大,那么,

  • 前面的“1”都不用变换;
  • 设字符串为“1...10...01+?” (从第一个“0”开始,它和与其相邻连续的k个“0”可以转换成k个“1”和一个“0”使字符串更大) ----> 设这里的第一个“0”位置为k(下标从0开始)
  • “?”部分中的“0”可以通过操作2全部移到标红的“1”的前面,也就是与前面的连续的“0”连起来,这样字符串就变成“1...10...01...1”(*),其中“0”和“1”的个数分别与原始字符串相同。 ----> 设一共有n个“0”
  • 然后再通过操作1将中间的n个“0”变成n-1个“1”和一个“0”,字符串变成“1...101...1”(**)。 ----> 唯一的“0”位置即为字符串(*)中最后一个“0”的位置,即k+n-1
  • 那么问题就变成找到这个唯一的“0”的位置,就能得到最后的字符串。上述文本中加粗部分即为思路。

代码如下:

class Solution(object):
    def maximumBinaryString(self, binary):
        """
        :type binary: str
        :rtype: str
        """
        n = len(binary)
        s = list(binary)
        k = -1
        m = 0
        res = ''
        for i in range(0, n):
            if s[i] == '0' and k == -1: 
                k = i      # 找到第一个0的位置
            if s[i] == '0':
                m += 1     # 统计0的个数

        for j in range(0, n):   
        # 得到最终的字符串,第k+m-1个位置为0,其他位置都为1
            if j == k+m-1:
                res += '0'
            else:
                res += '1'
        return res

提交通过:

 

### Java 实现 LeetCode 第 3 题:无重复字符的最长子串 以下是基于滑动窗口算法的 Java 解决方案,该方法通过维护一个动态窗口来高效解决问题。此解法的时间复杂度为 O(n),空间复杂度为 O(min(m, n)),其中 m 是字符串中不同字符的数量。 #### 滑动窗口原理 滑动窗口的核心思想是利用两个指针 `left` 和 `right` 来表示当前正在考察的子串范围。当发现有重复字符时,移动左边界直到不再存在重复字符为止[^1]。 ```java public class Solution { public int lengthOfLongestSubstring(String s) { if (s == null || s.length() == 0) return 0; int maxLength = 0; int left = 0; // 左边界初始位置 Map<Character, Integer> charIndexMap = new HashMap<>(); for (int right = 0; right < s.length(); right++) { // 右边界逐步扩展 char currentChar = s.charAt(right); if (charIndexMap.containsKey(currentChar) && charIndexMap.get(currentChar) >= left) { // 如果当前字符已经存在于哈希表中,则更新左边界到上一次出现的位置之后 left = charIndexMap.get(currentChar) + 1; } charIndexMap.put(currentChar, right); // 更新或记录当前字符及其索引 maxLength = Math.max(maxLength, right - left + 1); // 计算最大长度 } return maxLength; } } ``` 上述代码实现了以下逻辑: - 使用 `HashMap` 存储每个字符最近一次出现的索引。 - 当遇到重复字符时,调整左边界至之前重复字符的下一个位置。 - 动态计算并保存最大的无重复子串长度[^2]。 #### 测试案例 为了验证程序的有效性,可以运行如下测试: ```java public static void main(String[] args) { Solution sol = new Solution(); System.out.println(sol.lengthOfLongestSubstring("abcabcbb")); // 输出: 3 ["abc"] System.out.println(sol.lengthOfLongestSubstring("bbbbb")); // 输出: 1 ["b"] System.out.println(sol.lengthOfLongestSubstring("pwwkew")); // 输出: 3 ["wke"] System.out.println(sol.lengthOfLongestSubstring("")); // 输出: 0 [] System.out.println(sol.lengthOfLongestSubstring("au")); // 输出: 2 ["au"] } ``` 这些测试涵盖了多种情况,包括空字符串、全相同字符以及正常输入场景下的表现[^3]。 #### 复杂度分析 时间复杂度:O(n),因为每个字符最多被访问两次——一次由右指针遍历,另一次可能因左指针移动而重新评估。 空间复杂度:O(min(m, n)),取决于字符串中的唯一字符数量与总长度之间的较小者[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值