美文网首页
Leetcode【423、593】

Leetcode【423、593】

作者: 牛奶芝麻 | 来源:发表于2019-07-21 22:07 被阅读0次
    问题描述:【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 情况:

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

    注意到正方形有一个特点:正方形四条边相等,两条对角线相等。因此,我们可以计算两两坐标之间的距离,得到 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】

          本文链接:https://www.haomeiwen.com/subject/tjrvlctx.html