Leetcode【423、593】

问题描述:【Math】423. Reconstruct Original Digits from English
解题思路:

这道题是给一个字符串,其中包含字母顺序打乱的英文单词表示的数字 0 - 9。按升序输出原始的数字。

这道题肯定是找每个英文单词的规律。首先容易想到先统计每个字符出现的次数;然后,注意到有些单词中存在独一无二的字符:"zero" 中的 "z","two" 中的 "w","four" 中的 "u","six" 中的 "x" 以及 "eight" 中的 "e",根据这个性质,可以先找出这些英文单词出现了几次;排除掉这些单词之后,剩下的 5 个单词其中 4 个也存在了独一无二的字符:"one" 中的 "o","three" 中的 "t","five" 中的 "f","seven" 中的 "s",按照上述方法继续操作;最后,剩下的 1 个单词 "nine" 中有独一无二的字符 "i"(也可以是 "e"),按照上述方法继续操作。最终,可以得到每个单词出现了几次,将结果升序排列输出即可。

这种做法类似于斯诺克运动中每次选择打哪颗红球的问题。刚开始,红球之间有干扰(单词之间存在相同字符),因此可以先选择独立的红球进行击打(选择存在独一无二的字符的单词);这样,红球之间的干扰会随着球的入袋而慢慢减少(存在独一无二的字符的单词已经统计完次数);那么,剩下的红球也就各自有了进球的路线(剩下的单词也存在了独一无二的单词)。

因此,在这道题中,我们需要找到一个存在第一无二字符的单词序列即可,比如 [0, 2, 4, 6, 8, 1, 3, 5, 7, 9],当然这种序列不唯一。

刚开始写了一个没有循环的代码,很长,但相对容易理解,代码如下:

Python3 实现:
class Solution:
    def originalDigits(self, s: str) -> str:
        sets = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
        cnt = [0] * 10  # 保存结果
        dic = collections.Counter(s)
        if dic['z'] > 0:
            cnt[0] = dic['z']
            tmp = dic['z']
            dic['z'] -= tmp; dic['e'] -= tmp; dic['r'] -= tmp; dic['o'] -= tmp
        if dic['w'] > 0:
            cnt[2] = dic['w']
            tmp = dic['w']
            dic['t'] -= tmp; dic['w'] -= tmp; dic['o'] -= tmp
        if dic['u'] > 0:
            cnt[4] = dic['u']
            tmp = dic['u']
            dic['f'] -= tmp;  dic['o'] -= tmp;  dic['u'] -= tmp;  dic['r'] -= tmp 
        if dic['x'] > 0:
            cnt[6] = dic['x']
            tmp = dic['x']
            dic['s'] -= tmp; dic['i'] -= tmp; dic['x'] -= tmp
        if dic['s'] > 0:
            cnt[7] = dic['s']
            tmp = dic['s']
            dic['s'] -= tmp; dic['e'] -= tmp; dic['v'] -= tmp; dic['e'] -= tmp; dic['n'] -= tmp
        if dic['v'] > 0:
            cnt[5] = dic['v']
            tmp = dic['v']
            dic['f'] -= tmp;  dic['i'] -= tmp;  dic['v'] -= tmp;  dic['e'] -= tmp
        if dic['g'] > 0:
            cnt[8] = dic['g']
            tmp = dic['g']
            dic['e'] -= tmp; dic['i'] -= tmp; dic['g'] -= tmp; dic['h'] -= tmp; dic['t'] -= tmp
        if dic['i'] > 0:
            cnt[9] = dic['i']
            tmp = dic['i']
            dic['n'] -= tmp; dic['i'] -= tmp; dic['n'] -= tmp; dic['e'] -= tmp
        if dic['n'] > 0:
            cnt[1] = dic['n']
            tmp = dic['n']
            dic['o'] -= tmp; dic['n'] -= tmp; dic['e'] -= tmp
        if dic['t'] > 0:
            cnt[3] = dic['t']
            tmp = dic['t']
            dic['t'] -= tmp; dic['h'] -= tmp; dic['r'] -= tmp; dic['e'] -= tmp; dic['e'] -= tmp
        # 结果输出
        ans = ""
        for i in range(10):
            ans += str(i) * cnt[i]
        return ans

更简洁的写法:

上述写法太繁琐,可以用下面更简洁的方法,思路都是一样的:

class Solution:
    def originalDigits(self, s: str) -> str:
        # 存储单词及其对应的独一无二的字符
        en = [("zero", "z"), ("one", "o"), ("two", "w"), ("three", "t"), ("four", "u"), ("five", "f"), ("six", "x"), ("seven", "s"), ("eight", "g"), ("nine", "i")]
        dic = collections.Counter(s)
        ans = ""  # 保存结果
        for i in [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]:  # 按照这个序列能够保证独一无二的字符
            n = dic[en[i][1]]  # 独一无二的字符出现的次数
            for ch in en[i][0]:  # 单词的每个字符减去独一无二的字符出现的次数
                dic[ch] -= n
            ans += str(i) * n
        return "".join(sorted(ans))  # 排序后输出结果

问题描述:【Math】593. Valid Square
解题思路:

这道题是给四个坐标,判断能否组成一个正方形。

刚开始的想法是按照 x 轴的坐标对四个点排序,然后根据点的坐标来判断。但是只考虑到了下图中的图 3 情况:

Leetcode【423、593】_第1张图片

当然除了上述三种情况还有其他的情况,根据点来判断不可行。

注意到正方形有一个特点:正方形四条边相等,两条对角线相等。因此,我们可以计算两两坐标之间的距离,得到 C(4, 2) = 6 个距离;然后,对这 6 个距离从小到大排序,前四个距离相同(较短的四条边相等)且不为 0、后两个距离相同(较长的两条对角线相等),则必定为正方形,返回 True;否则,返回 False。

Python3 实现:
class Solution:
    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:
        def dist(x, y):  # 计算两点之间的距离
            return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2
        # 计算四边形共6种组合的距离并排序
        dists = sorted([dist(p1, p2), dist(p1, p3), dist(p1, p4), dist(p2, p3), dist(p2, p4), dist(p3, p4)])
        # 距离不为0且有两种距离的四边形是正方形
        if dists[0] != 0 and dists[0] == dists[1] == dists[2] == dists[3] and dists[4] == dists[5]:
            return True
        else:
            return False

你可能感兴趣的:(Leetcode【423、593】)