LeetCode:每日一题【第二周】

8.8 ~ 8.14 尽量坚持刷力扣的每日一题,锻炼大脑思维。更新中~~

761. 特殊的二进制序列【递归分治】

题目描述

在这里插入图片描述

思路

题目要求0和1的数量相同,我们可以看成()括号匹配,意思就是让括号有效匹配的情况下,尽量让大量的左括号在前面。并且第一个字符一定是1,最后一个字符一定是0,其实证明也好证明,如果第一个数字为0,则以第一个数字为前缀,就不满足题目中的第二个条件,如果最后一个字符是1,则前n- 1的前缀则也不满足第二个条件。我们可以剔除1和0的情况,继续进行分治讨论,知道s的长度小于等于2的情况,只有两种情况,就是10以及空字符串,直接返回即可。递归返回后,将所有特殊字符按降序返回。

AC代码

class Solution:
    def makeLargestSpecial(self, ss: str) -> str:
        # 内置函数
        def dfs(s):
            if len(s) <= 2:
                return s

            cnt, left = 0, 0
            subs = list()
            for i, ch in enumerate(s):
                if ch == '1':
                    cnt += 1
                else:
                    cnt -= 1
                    # 找到一组特殊序列
                    if cnt == 0:
                        subs.append("1" + dfs(s[left + 1:i]) + "0")
                        left = i + 1
            subs.sort(reverse=True)
            return "".join(subs)

        return dfs(ss)

1413. 逐步求和得到正数的最小值【思维题】

题目描述

在这里插入图片描述

思路

变量数组,找最小前缀和,如果大于等于0,则都是大于等于0的数,则只需要输出1即可,如果小于0,则输出相反数+1

AC代码

class Solution:
    def minStartValue(self, nums: List[int]) -> int:
        tmp, s = 1, 0
        for num in nums:
            s += num
            tmp = min(tmp, s)
        if tmp >= 0:
            return 1
        else:
            return -tmp + 1

640. 求解方程【模拟】

题目描述

在这里插入图片描述

思路

将右边全部项移到左边,统计x系数和常量值,得到kx + val = 0, kx = -val. 分三类情况:

  • 1.有解,k不为0,最后输出,x = -val/k
  • 2.无解,k = 0,val不为0,最后输出“No solution”
  • 3.有无穷解, k = val = 0,最后输出“Infinite solution”
    思路,用sign1作为等号左边项还是右边项的标记,sign2作为±号的标记。初始sign1 = 1,遇到等号sign1变为-1,sign2的正负与解析到正负有关。num记录单项常数(这里包括x项的常数),valid标识number是否有效,比如x = x就没有效。

AC代码

class Solution:
    def solveEquation(self, equation: str) -> str:
        k = val = i = 0
        n, sign1= len(equation), 1
        while i < n:
            if equation[i] == '=':
                i += 1
                sign1 = -1
                continue
            sign2 = sign1
            if equation[i] == '+':
                i += 1
            elif equation[i] == '-':
                i += 1
                sign2 = -sign2

            num, valid = 0, False
            while i < n and equation[i].isdigit():
                valid = True
                num = num * 10 + int(equation[i])
                i += 1
            if i < n and equation[i] == 'x':
                k += sign2 * num if valid else sign2
                i += 1
            else:
                val += sign2 * num
        if k == 0:
            return "Infinite solutions" if val == 0 else "No solution"
        return "x={}".format(-val//k)

1417. 重新格式化字符串【思维】

题目描述

在这里插入图片描述

思路

分别将数字和字符分成两个数组,然后交叉组合。

AC代码

class Solution:
    def reformat(self, s: str) -> str:
        tmp1 = tmp2 = ""
        for ch in s:
            if '0' <= ch <= '9':
                tmp1 += ch
            else:
                tmp2 += ch
        if abs(len(tmp1) - len(tmp2)) >= 2:
            return ""
        if len(tmp1) < len(tmp2):
            tmp1, tmp2 = tmp2, tmp1
        ans = ""
        for i in range(len(tmp2)):
            ans += tmp1[i] + tmp2[i]
        if len(tmp1) != len(tmp2):
            ans += tmp1[len(tmp2)]
        return ans

1282. 用户分组【哈希】

题目描述

在这里插入图片描述

思路

用哈希表存储每个值对应的下标,之后在值中找该值大小的下标个数压入列表

AC代码

class Solution:
    def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]:
        groups = defaultdict(list) # defaultdict函数,当遇到空的键时,有默认值
        for i, size in enumerate(groupSizes): # enumerate函数可以获得下标和对应值
            groups[size].append(i)
        ans = []
        for size, people in groups.items(): # items函数能获得字典的键值对
            ans.extend(people[i : i + size] for i in range(0, len(people), size))
        return ans

768. 最多能完成排序的块 II【单调栈】

题目描述

在这里插入图片描述

思路

通过题目示例我们可以发现,每一个分组的最大值,都是右边大于左边,因此可以用单调栈来维护每个分组的最大值。

  • 如果当前值大于等于最右边的分组最大值,则会产生新的一个分组。
  • 如果小于,则需要向左边走,直到大于等于某个分组的最大值停止,然后将后面的分组和当前分组融合成一个分组,用最后一个分组的最大值表示。
  • 每个分组只需要存最大值

AC代码

class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        # 运用单调栈的思想
        stack = []
        for a in arr:
            # 如果栈为空或最后一个分组的最大数小于等于a,则产生新的分组
            if len(stack) == 0 or a >= stack[-1]:
                stack.append(a)
            else:
                # 否则,将从右往左找适当的分组加入,且后面的分组和当前的分组融合成一个分组,且把最大值更新
                mx = stack.pop()
                while stack and a < stack[-1]:
                    stack.pop()
                stack.append(mx)
        return len(stack)

1422. 分割字符串的最大得分

题目描述

在这里插入图片描述

思路

  • 统计0的前缀和,以及1的后缀和(可用num1-前缀和来算)
  • 将0的前缀和与1的后缀和相加,就是答案
  • 注意:必须是两个非空数组,所以下标不能到n-1,不然第二个就是空数组

AC代码

class Solution:
    def maxScore(self, s: str) -> int:
        n = len(s)
        arr_0 = [0] * n
        arr_1 = [0] * n
        num_0 = num_1 = 0
        for i,ch in enumerate(s):
            if ch == '0':
                num_0 += 1
            else:
                num_1 += 1
            arr_0[i] = num_0
            arr_1[i] = num_1
        ans = 0
        for i in range(n - 1):
            ans = max(ans, arr_0[i] + num_1 - arr_1[i])
        return ans

一行代码搞定

  return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s)))

猜你喜欢

转载自blog.csdn.net/qq_45249273/article/details/126224364
今日推荐