LeetCode 1641. 统计字典序元音字符串的数目 / 1637. 两点之间不包含任何点的最宽垂直区域 / 1053. 交换一次的先前排列

1641. 统计字典序元音字符串的数目

2023.3.29 每日一题

题目描述

给你一个整数 n,请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。

字符串 s 按 字典序排列 需要满足:对于所有有效的 i,s[i] 在字母表中的位置总是与 s[i+1] 相同或在 s[i+1] 之前。

示例 1:

输入:n = 1
输出:5
解释:仅由元音组成的 5 个字典序字符串为 [“a”,“e”,“i”,“o”,“u”]

示例 2:

输入:n = 2
输出:15
解释:仅由元音组成的 15 个字典序字符串为
[“aa”,“ae”,“ai”,“ao”,“au”,“ee”,“ei”,“eo”,“eu”,“ii”,“io”,“iu”,“oo”,“ou”,“uu”]
注意,“ea” 不是符合题意的字符串,因为 ‘e’ 在字母表中的位置比 ‘a’ 靠后

示例 3:

输入:n = 33
输出:66045

提示:

1 <= n <= 50

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

思路

找规律

class Solution:
    def countVowelStrings(self, n: int) -> int:
        # 如果是n=1,那么有5个,这时候以每个字符结尾的各有1个
        # 如果是n=2,那么就是在5个字符后面加字符,也就是加了5,4,3,2,1个,共15个,这时候每个字符结尾的分别1,2,3,4,5个,
        # 如果n=3,那么在n=2的基础上加字符,因为n=2中的字符是排好序的,那么再往后加
        # a后面能加5种,e能4种,i能3种...
        # 所以n=3就是,1*5 + 2*4 + 3*3 + 4*2 + 5*1 = 35个
        # 此时以5个字符结尾的分别有 1,3, 6, 10, 15,也就是n=2的时候的前缀和
        #1 4 10 20 35
        #1 5 15 35 70

        start = [1,1,1,1,1]
        for i in range(n - 1):
            for j in range(1, 5):
                start[j] = start[j - 1] + start[j]
        
        return sum(start)

看成排列组合问题,顺便复习排列组合公式

class Solution:
    def countVowelStrings(self, n: int) -> int:
        # 看成有n个选择,选择5个元音代表的盒子,有多少种选择,盒子可以为空,比如都选a
        # 因为字母的顺序是规定好的,选择完以后,就可以排成唯一一个长度为n的字符串
        # 这样就变成了一个排列组合的问题,那么怎么算这个呢
        # 看到很巧妙的解释
        # 如果不能为空,那么就相当于给n个球中间插入挡板,即n-1个位置插入m-1个挡板,即C(n-1,m-1)
        # 那如果可以为空,就相当于先给m个盒子里放m个球,然后再放n个球进去,
        # 此时问题就变成了m+n个球放在m个盒子里,即C(m+n-1, m-1)
        # 那么这道题就变成了C(n+4, 4)

        return comb(n + 4, 4)

1637. 两点之间不包含任何点的最宽垂直区域

2023.3.30 每日一题

题目描述

给你 n 个二维平面上的点 points ,其中 points[i] = [xi, yi] ,请你返回两点之间内部不包含任何点的 最宽垂直区域 的宽度。

垂直区域 的定义是固定宽度,而 y 轴上无限延伸的一块区域(也就是高度为无穷大)。 最宽垂直区域 为宽度最大的一个垂直区域。

请注意,垂直区域 边上 的点 不在 区域内。

示例 1:

输入:points = [[8,7],[9,9],[7,4],[9,7]]
输出:1
解释:红色区域和蓝色区域都是最优区域。

示例 2:

输入:points = [[3,1],[9,0],[1,0],[1,4],[5,3],[8,8]]
输出:3

提示:

n == points.length
2 <= n <= 10^5
points[i].length == 2
0 <= xi, yi <= 10^9

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

思路

class Solution:
    def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
        # 我只要把这个数组排序,然后找一下两个最长距离的点就行
        # points = sorted(points, key = lambda x : x[0])
        points.sort()
        return max([(points[i + 1][0] - points[i][0]) for i in range(len(points) - 1)])

1053. 交换一次的先前排列

2023.04.03 每日一题

题目描述

给你一个正整数数组 arr(可能存在重复的元素),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大排列。

如果无法这么操作,就请返回原数组。

示例 1:

输入:arr = [3,2,1]
输出:[3,1,2]
解释:交换 2 和 1

示例 2:

输入:arr = [1,1,5]
输出:[1,1,5]
解释:已经是最小排列

示例 3:

输入:arr = [1,9,4,6,7]
输出:[1,7,4,6,9]
解释:交换 9 和 7

提示:

1 <= arr.length <= 10^4
1 <= arr[i] <= 10^4

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

思路

其实很简单的思路,就是从后往前找到第一个升序的位置,这个位置就是要交换的位置
然后再在这个位置x后面找到一个合适的值交换,什么是合适的值呢?就是在x位置后面,比x位置数小的最大值
要注意数相同的情况,在第一轮寻找过程中,找到了合适的数,因为越后面的数交换,得到的数越大,所以找到的是从后往前找第一个数
但是在第二轮寻找中,从x位置往右找,如果找到了比x小的最大值,但是有多个,那么交换的是最左边的,因为这样能使得交换后的值是较大的

class Solution:
    def prevPermOpt1(self, arr: List[int]) -> List[int]:
        # 小于arr的最大序列,就是大换小
        # 突然发现arr[i]的范围不是个位数,而是10的4次方
        # 好像不太影响
        # 因为换后面的数肯定比换前面的数要影响小,所以从后往前搜索
        # 可以从后往前找到比当前最小值大的一个数,位置是idx,此时找到了需要交换的位置
        # 然后再在idx:l中,找到比idx位置数x小但是最大的数,然后交换
        
        l = len(arr)
        minx = arr[-1]
        chidx = l + 1
        for i in range(l - 2, -1, -1):
            # 如果发现比当前最小值大了,那么找到了可交换的位置
            # print(arr[i])
            if arr[i] > minx:
                chidx = i 
                break
            minx = arr[i]

        if chidx == l + 1:
            return arr
        # print(chidx)
        maxidx = chidx + 1
        temp = arr[chidx + 1]
        for i in range(chidx + 2, l):
            # 如果找到的这个值大于等于要交换位置的数值了,说明这个位置的前一个位置就是要交换的位置
            if arr[i] < arr[chidx] and arr[i] > temp:
                temp = arr[i]
                maxidx = i
            
        arr[maxidx], arr[chidx] = arr[chidx], arr[maxidx]
        return arr
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值