Leetcode 【553、609、856、1003、1023】

题目描述:【Math】553. Optimal Division
解题思路:

这道题是给一个数组,各个数字连除,通过加括号,使得除操作的结果最大。刚开始想着是遍历所有加括号的方式,然后求出最大结果。但是,发现加括号的规律很麻烦。

后来又重新读了一下题目,发现数组中的数字取值是 [2,1000]。就这说明,如果我们不加括号,n1/n2/n3/n4/n5 只会越除越小。那么加括号如何保证最大结果呢?其实很简单,我们只需要在第二个数到最后一个数加括号即可,得到 n1/(n2/n3/n4/n5),因为 n2/n3/n4/n5 是能过够获得的最小的除数因子,然后 n1 作为被除数,除以一个最小的除数,当然能获得最大的结果。

因此,此题转变为格式化输出的问题。这是一道数学题~

Python3 实现:
class Solution:
    def optimalDivision(self, nums: List[int]) -> str:
        if len(nums) == 1:
            return str(nums[0])
        elif len(nums) == 2:
            return str(nums[0]) + "/" + str(nums[1])
        else:  # 在第二个数前到最后一个数后加括号就是答案
            ans = str(nums[0]) + "/("  # 拼接答案
            for i in range(1, len(nums) - 1):
                ans += str(nums[i]) + "/"
            ans += str(nums[-1]) + ")"
            return ans

最后一个 else 也可以直接写成:

return "%s/(%s)" % (str(nums[0]), '/'.join(nums[1:]))

题目描述:【Hash Table】609. Find Duplicate File in System
解题思路:

这道题是给一个字符串数组,每一项包括文件路径、文件名、文件内容。要求找到所有重复的文件(至少两个),按照文件内容分组,每个分组的内容是各个重复文件的路径。

看到题目很容易想到利用字典来存储,字典的键为文件内容,字典的值是一个列表,保存重复文件的各个路径(相当于字典中每一项是一个分组)。最后,返回字典中所有列表长度 >= 2 的值就是结果(重复文件分组至少为两个)。

Python3 实现:
class Solution:
    def findDuplicate(self, paths: List[str]) -> List[List[str]]:
        dic = dict()
        for path in paths:
            items = path.split(" ")
            directory = items[0]  # 根目录
            for i in range(1, len(items)):
                ind = items[i].find('(')
                content = items[i][ind+1:-1]  # 文件内容
                if content not in dic:  # 构造分组,键为文件内容,值为文件路径
                    dic[content] = [directory+"/"+items[i][:ind]]
                else:
                    dic[content].append(directory+"/"+items[i][:ind])
        return [v for v in dic.values() if len(v) >= 2]  # 长度>=2的是一个分组

题目描述:【Stack】856. Score of Parentheses
解题思路:

这道题是给一个平衡括号字符串,给了三个规则来计算平衡字符串的分数。首先很容易想到用栈来解决。因为我们要计算得分,所以栈中存储 '(' 是没有意义的,我们可以在栈中存储得分。

做法是:从左到右遍历字符串 S,当我们遇到 '(' 时,就在栈中压入 0。遇到 ')' 时,如果栈顶是 0,相当于得到一个 "()",计分为 1,并把 1 压入栈中;如果栈顶不是 0,我们通过循环把栈中非零数一个个取出来,同时累加这些非零数。所有非零数取出来后,这个累加的结果再乘以 2 就是最终的当前的得分。遍历完成后,栈中一定只剩下几个非零数,对它们求和就是最后的总得分。

举个例子,对于 S = "(()(()))(()()())",我们栈中的变化情况是:[0] -> [0 0] -> [0 1] -> [0 1 0] -> [0 1 0 0] -> [0 1 0 1] -> [0 1 2] (取出非零数 1,然后乘以 2)-> [6] (取出非零数 1、2 累加,然后乘以 2)-> [6 0] -> [6 0 0] -> [6 0 1] -> [6 0 1 0] -> [6 0 1 1] -> [6 0 1 1 0] -> [6 0 1 1 1] -> [6 6](取出非零数 1、1、1 累加,然后乘以 2)。因此,当遍历完 S 后,栈中剩下的一定是非零数 [6 6],这些非零数满足规则 2 (AB),因此对它们求和就是最终的答案 12。

Python3 实现:
class Solution:
    def scoreOfParentheses(self, S: str) -> int:
        stack = []
        for s in S:
            if s == '(':
                stack.append(0)
            else:
                t = 0  # 累加值
                v = stack.pop()
                while v != 0:  # 找出非零数进行累加
                    t += v
                    v = stack.pop()
                stack.append(max(t*2, 1))  # 将累加值或者1压入栈中
        return sum(stack)  # 将栈中结果求和就是最后的分数

print(Solution().scoreOfParentheses("(()(()))(()()())"))  # 12

题目描述:【String、Stack】1003. Check If Word Is Valid After Substitutions
解题思路:

这道题给了一个有效字符串 "abc",然后定义有效字符串 V,V 划分成 X 和 Y 两部分,并且满足 X + "abc" + Y (X、Y可以为空)。求给一个字符串,看它是否是有效的。

方法1(朴素解法,可能超时):

因为有效字符串一定包括 "abc",因此直接的想法是遍历字符串,然后连续三个字符是 "abc" 就将其删除,然后将索引重新置 0,从头再次遍历寻找。这样时间复杂度为 O(n^2),提交会超时。后来发现有效字符串一定是以 'a' 开头,以 'c' 结尾,因此加了个判断,AC 了。算是投机取巧吧,这种方法不建议。

Python3 实现:

class Solution:
    def isValid(self, S: str) -> bool:
        if S[0] != 'a' or S[-1] != 'c':  # 提前终止
            return False
        i = 0
        while i < len(S) - 2:
            if S[i:i+3] == "abc":
                S = S[:i] + S[i+3:]  # 拼接的时间复杂度为O(n)
                i = 0  # 从索引0开始继续寻找
            else:
                i += 1
        if len(S) == 0:
            return True
        else:
            return False

方法2 (栈,时间复杂度和空间复杂度均为 O(n)):

方法1每次删除字符串 "abc" 的时间复杂度为 O(n)(采取拼接的方式删除 "abc"),且每次索引位置回退为 0,效率很低。因此,可以想到使用栈来记录状态。如果栈中有 "abc",就出三次栈,弹出 "abc",且这种做法索引不需要回退。最后,栈为空说明是一个有效串,时间复杂度和空间复杂度均为 O(n)。

Python3 实现:

class Solution:
    def isValid(self, S: str) -> bool:
        stack = []
        for s in S:
            stack.append(s)
            if stack[-1:-4:-1] == ['c','b','a']:  # 如果栈中有"abc",出三次栈
                stack.pop(); stack.pop(); stack.pop()
        return len(stack) == 0

方法3(str.replace("abc", "") 的巧妙使用):

方法1使用拼接的方式来删除字符串 "abc" 的时间复杂度为 O(n),效率很低。其实,在字符串操作中,有一个方法 str.replace("abc", "") 同样可以进行字符串的删除,效率比拼接的方式高。并且,str.replace("abc", "") 可以一次性替换字符串中所有 "abc" 为空串。

因此,当我们操作多次 str.replace("abc", "")后,如果字符串长度为 0,说明是一个有效串;如果前后两次操作 str.replace("abc", "") 字符串长度不变化,说明不是一个有效串,返回 False 即可。

这种方法击败了 97% 的提交,效率很高。

Python3 实现:

class Solution:
    def isValid(self, S: str) -> bool:
        if S[0] != 'a' or S[-1] != 'c':  # 提前终止
            return False
        last_len = len(S)  # 前后两次字符串的长度
        while True:
            if len(S) == 0:
                return True
            S = S.replace("abc", "")  # 删除当前字符串中所有"abc"字串
            if last_len == len(S):  # 前后两次长度不变化,不是有效串
                return False
            else:
                last_len = len(S)

题目描述:【String】1023. Camelcase Matching
解题思路:

这道题是给一个字典和模式串,从字典中找出模糊匹配模式串的所有单词。但是除了模式串本身,其他匹配的字符都是小写字母。

这道题最直接的想法就是字典中的每个单词和模式串逐个字符比对即可。只不过有很多细节再需要注意:

  • 如果单词 query 的每个位置 i,如果 query 当前字符 query[i] 和模式串位置 j 的字符 pattern[i] 相等,则 j 向后移动一位;如果 j 等于 pattern 的长度,说明模式串可以匹配当前单词,但是还要注意单词后面的字符不能有大写字母,如果有大写字母,则还是不满足题意。
  • 如果 query[i] 是小写字母,则跳过继续向后搜寻;
  • 其他情况 query[i] 均不满足模式串。
  • 遍历完 query 后,j 有可能小于 pattern 长度,如 query = "F",pattern = "FB",因此还要判断如果 j < len(pattern),不满足题意。

因此,这道题没有什么技巧,就是要认真考虑模糊匹配的各种情况,防止出错。

Python3 实现:
class Solution:
    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:
        ans = []
        for query in queries:
            j = 0  # 模式串匹配位置
            flag = True  # 标记匹配成功还是失败
            for i in range(len(query)):
                if query[i] == pattern[j]:
                    j += 1
                    if j == len(pattern):
                        if len(query[i+1:]) > 0 and query[i+1:].islower() == False:  # 单词后面的字符必须是小写
                            flag = False
                        break
                elif 'a' <= query[i] <= 'z':
                    continue
                else:
                    flag = False
                    break
            if j < len(pattern):  # 单词长度可能小于模式串长度
                flag = False
            ans.append(flag)
        return ans
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,381评论 0 5
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,101评论 1 32
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,746评论 0 10
  • Django 准备 “虚拟环境为什么需要虚拟环境:到目前位置,我们所有的第三方包安装都是直接通过 pip inst...
    33jubi阅读 1,326评论 0 5
  • 拼多多属于平台电商,商业模式类似线下购物中心/小商品城,平台为上架提供销售场景,向B/C端商家收费,收入来自店铺租...
    YK_自律自由阅读 58,008评论 3 55