LeetCode 1624. 两个相同字符之间的最长子字符串 / 698. 划分为k个相等的子集 / 面试题 01.08. 零矩阵 / 1694. 重新格式化电话号码

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1624. 两个相同字符之间的最长子字符串 / 698. 划分为k个相等的子集 / 面试题 01.08. 零矩阵 / 1694. 重新格式化电话号码相关的知识,希望对你有一定的参考价值。

1624. 两个相同字符之间的最长子字符串

2022.9.17 每日一题

题目描述

给你一个字符串 s,请你返回 两个相同字符之间的最长子字符串的长度 ,计算长度时不含这两个字符。如果不存在这样的子字符串,返回 -1 。

子字符串 是字符串中的一个连续字符序列。

示例 1:

输入:s = “aa”
输出:0
解释:最优的子字符串是两个 ‘a’ 之间的空子字符串。

示例 2:

输入:s = “abca”
输出:2
解释:最优的子字符串是 “bc” 。

示例 3:

输入:s = “cbzxy”
输出:-1
解释:s 中不存在出现出现两次的字符,所以返回 -1 。

示例 4:

输入:s = “cabbac”
输出:4
解释:最优的子字符串是 “abba” ,其他的非最优解包括 “bb” 和 “” 。

提示:

1 <= s.length <= 300
s 只含小写英文字母

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-substring-between-two-equal-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution:
    def maxLengthBetweenEqualCharacters(self, s: str) -> int:
        d = 
        for i, c in enumerate(s):
            if c in d:
                d[c].append(i)
            else:
                d[c] = [i]
        maxlen = -1
        for v in d.values():
            if v[-1] - v[0] - 1 > maxlen:
                maxlen = v[-1] - v[0] - 1
        return maxlen

698. 划分为k个相等的子集

2022.9.20 每日一题

题目描述

给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。

示例 1:

输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
输出: True
说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。

示例 2:

输入: nums = [1,2,3,4], k = 3
输出: false

提示:

1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
每个元素的频率在 [1,4] 范围内

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/partition-to-k-equal-sum-subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution:
    def canPartitionKSubsets(self, nums: List[int], k: int) -> bool:
        # 数字不多,最多16个所以想到了状态压缩
        # 加上动态规划或者记忆化搜索

        total = sum(nums)
        if total % k:
            return False
        per = total // k  # 每一份的值
        nums.sort()
        if nums[-1] > per:
            return False
        n = len(nums)
        @cache
        def dfs(dp, cur):
            if dp == 0:
                return True

            for i in range(n):
                # 如果当前数加上当前值大于部分值,则跳出循环
                if nums[i] + cur > per:
                    break
                # 如果当前位置的数仍然存在,那么加上这个数
                if dp >> i & 1:
                    if dfs(dp ^ (1 << i), (cur + nums[i]) % per):
                        return True
            return False

        return dfs((1 << n) - 1, 0)

面试题 01.08. 零矩阵

2022.9.30 每日一题

题目描述

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例 1:

输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]

示例 2:

输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zero-matrix-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

之前做过的题,在原矩阵上修改,最少可以用一个变量来标记第一列是否有0
然后在第一行和第一列标记该行该列是否有0
从下到上进行修改,防止第一行提前被修改

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])
        flag = False

        for i in range(m):
            if matrix[i][0] == 0:
                flag = True
            for j in range(1, n):
                if not matrix[i][j]:
                    matrix[i][0] = 0
                    matrix[0][j] = 0

        for i in range(m - 1, -1, -1):
            for j in range(1, n):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0
            if flag:
                matrix[i][0] = 0

1694. 重新格式化电话号码

2022.10.1 每日一题 国庆快乐

题目描述

给你一个字符串形式的电话号码 number 。number 由数字、空格 ’ '、和破折号 ‘-’ 组成。

请你按下述方式重新格式化电话号码。

  • 首先,删除 所有的空格和破折号。
  • 其次,将数组从左到右 每 3 个一组 分块,直到 剩下 4 个或更少数字。剩下的数字将按下述规定再分块:
    • 2 个数字:单个含 2 个数字的块。
    • 3 个数字:单个含 3 个数字的块。
    • 4 个数字:两个分别含 2 个数字的块。

最后用破折号将这些块连接起来。注意,重新格式化过程中 不应该 生成仅含 1 个数字的块,并且 最多 生成两个含 2 个数字的块。

返回格式化后的电话号码。

示例 1:

输入:number = “1-23-45 6”
输出:“123-456”
解释:数字是 “123456”
步骤 1:共有超过 4 个数字,所以先取 3 个数字分为一组。第 1 个块是 “123” 。
步骤 2:剩下 3 个数字,将它们放入单个含 3 个数字的块。第 2 个块是 “456” 。
连接这些块后得到 “123-456” 。

示例 2:

输入:number = “123 4-567”
输出:“123-45-67”
解释:数字是 “1234567”.
步骤 1:共有超过 4 个数字,所以先取 3 个数字分为一组。第 1 个块是 “123” 。
步骤 2:剩下 4 个数字,所以将它们分成两个含 2 个数字的块。这 2 块分别是 “45” 和 “67” 。
连接这些块后得到 “123-45-67” 。

示例 3:

输入:number = “123 4-5678”
输出:“123-456-78”
解释:数字是 “12345678” 。
步骤 1:第 1 个块 “123” 。
步骤 2:第 2 个块 “456” 。
步骤 3:剩下 2 个数字,将它们放入单个含 2 个数字的块。第 3 个块是 “78” 。
连接这些块后得到 “123-456-78” 。

示例 4:

输入:number = “12”
输出:“12”

示例 5:

输入:number = "–17-5 229 35-39475 "
输出:“175-229-353-94-75”

提示:

2 <= number.length <= 100
number 由数字和字符 ‘-’ 及 ’ ’ 组成。
number 中至少含 2 个数字。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reformat-phone-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

先去掉非数字的字符,然后再分组

class Solution:
    def reformatNumber(self, number: str) -> str:
        number = number.replace(' ', '')
        number = number.replace('-', '')
        l = len(number)
        s = ''
        i = 0
        while i < l:
            if l - i == 4:
                s += number[i : i + 2] + '-' + number[i + 2 : l]
                break
            elif l - i < 4:
                s += number[i : l]
                break
            s += number[i : i + 3] + '-'
            i += 3
        return s

用正则进行替换,再用join连接列表

class Solution:
    def reformatNumber(self, number: str) -> str:
        # 用正则替换,用join进行列表的连接
        number = re.compile(r"[- ]").sub("", number)
        idx, n, ans = 0, len(number), []
        while idx + 4 < n:
            ans.append(number[idx:idx+3])
            idx += 3
        if n - idx == 4:
            ans.append(number[idx:idx+2])
            idx += 2
        ans.append(number[idx:n])
        return "-".join(ans)

以上是关于LeetCode 1624. 两个相同字符之间的最长子字符串 / 698. 划分为k个相等的子集 / 面试题 01.08. 零矩阵 / 1694. 重新格式化电话号码的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1624. 两个相同字符之间的最长子字符串 / 698. 划分为k个相等的子集 / 面试题 01.08. 零矩阵 / 1694. 重新格式化电话号码

LeetCode 821 字符的最短距离[暴力 字符串] HERODING的LeetCode之路

检查具有数字和字符数据的 2 个数据帧之间差异的最有效方法?

Leetcode之821.字符的最短距离

leetcode:Word Ladder II

两个字符串之间的最短路径