Leetcode--String

8. String to Integer (atoi)

  • ls = list(str.strip()) 先去除字符串两端的空格,并把它存放到数组里。
  • 检查字符串首位是正号还是负号,检查完并给sign赋值后,将字符串首位删掉
  • 初始化res和循环变量i,while i<len(ls) and ls[i].isdigit(), 注意判断的条件。判断的是数组的长度,已经不再是字符串的长度了。还有就是要对数组每一位判断是否为数字。
    -res = res*10 + ord(ls[i]) - ord('0')
  • return max(-2**31, min(2**31-1, res*sign)) 这里是注意数组越界情况

12. Integer to Roman

运用/和%运算来取得四位数的第1,2,3,4个数字,然后将这个数字作为索引去相应的list里找罗马数字。
罗马数字个位数:Q = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
十位数:W = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
百位数:E = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
千位数: R = ["", "M", "MM", "MMM"]
注意第一个元素应该是空,这样可以使下标与数字对应起来。

13. Roman to Integer

初始化一个dict,里边存放所有的罗马字符和他们相对应的数字:
roman = {'M':1000, 'D':500, 'C':100, 'L':50, 'X':10, 'V':5, 'I':1}
罗马数字的计算规则:

  1. 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3
  1. 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8
  2. 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4
  3. 正常使用时,连续的数字重复不得超过三次
  4. 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)

python中string可以直接以List的形式访问。
所以当roman[s[i]] < roman[s[i+1]]时,就将res -= roman[s[i]],否则res += roman[s[i]], res初始化为0.
**需要注意的是,最后一个罗马字符永远是加上去的,不符合上述规律,所有要返回return res + roman[s[-1]]

14. Longest Common Prefix

运行时间为O(m*n), m为字符串最小长度,n为字符串个数
找每个string的公共最长prefix,举例说明:

  1. {"a","a","b"} should give "" as there is nothing common in all the 3 strings.
  1. {"a", "a"} should give "a" as a is longest common prefix in all the strings.
  2. {"abca", "abcd"} as abc
  3. {"ac", "ac", "a", "a"} as a.

先找出最短的string,以它作为标准。min()函数可以添加key = len属性,来找到最短长度的元素: shortest = min(strs, key = len)
然后针对shortest中的每一个字符,检查strs中的其他字符串相对应的位置是不是该字符,若不是,则返回shortest[:i],对shortest遍历时用enumerate比较方便。最后若都存在,就返回shortest

17. Letter Combinations of a Phone Number

Iterative:

思路在于要维护一个last数组,存放针对当前未组合的一个string,已经组合好的上一组string集合。有点类似于backtracking.
所以last一开始是为空的,取得第一个字符对应的string后,将string里的每个字符与last数组里的每一个string进行连接,append到一个新的数组里。最后再将新的数组作为last进行下一轮循环。需要注意的是,为什么要存在这个中间数组,以及什么时候对它进行初始化。
还是要想清楚这道题的思路,最后的结果数组,也就是我们的last数组,是在不断被替换更新的。它不可以直接append进新的字符串,因为老的字符串依然存在,但我们以及不需要了。所以我们需要一个中间数组来存放新一轮的结果,每次循环结束再将它赋值给last。并且这个中间数组要每次外层循环都更新为空。

  • 还有重要的一点就是,注意字符连接顺序。要使last中的字符再前,新加的字符在后。

Recursive

backtracking思想,不断传递除了最后一个字符的数字符串进去,总会有某一次,传进去的数字符串长度为1. 当数字符串长度为1时,返回list形式的相对应的string。
if len(digits)==1: return list(dic[digits[0]])
然后将数字符串最后一个数字符所对应的string取出来,最后将迭代的结果,和最后一个字符串对应的string相加。

last = self.letterCombinations(digits[:-1])
first = dic[digits[-1]]
return [ele + char for ele in last for char in first]

20. Valid Parentheses

  • 先说一种比较投机取巧的方法,用字符串中的replace函数。
while '()' in s or '[]' in s or '{}' in s:
      s = s.replace('()', '').replace('{}', '').replace('[]', '')
if len(s) == 0:
      return True
else:
      return False
  • 另外一种方法用到了stack和hash,将右括号作为key,左括号作为value存到哈希表中。然后对s中的每个字符进行遍历,如果char在value里if char in dic.values(),就将这个char append到stack中,如果char在Keyif char in dic.keys()里,就从stack里Pop出来一个元素与char在dic里所对应的value比较,如果不相等,就证明Invalid。这里要注意pop之前应该先判断stack是否为空。最后返回stack是否为空,因为每针对一个右括号,我们都会pop出来一个左括号,所以最后stack是空的。
    因为如果是valid的,我们就总是先遇到左括号,所以将左括号作为value,并加入到stack里。
  • 如果s的长度为奇数,就一定不是valid, 可以直接返回false,但注意当s长度为0时,我们认为他是valid的,返回true。

28. Implement strStr()

在一个字符串中找到另一个字符串第一次出现的位置。trick的点在于对大字符串进行for循环遍历时,range的范围是for i in range(len(str1) - len(str2) + 1):, 因为如果str2的长度是3,那在str1中就要3个3个的进行比较,所以在str1只剩最后三个字符时就要停止比较,所以将len(str2)减去,加1是因为range取不到最后一位,为了取到,就多加上一个。
if str1[i : i + len(str2)] == str2: return i 这就是上述3个3个的比较的实现,注意这里就不用再加1了。因为i + len(str2)本来就比实际长度多了一个。

22. Generate Parentheses

  • 先对left,right,list初始化,left, right, list = n, n, []
  • 调用dfs函数,self.dfs(left, right, list, ''),最后一个空字符串是用来存放valid排列的
  • 当左右都不存在的时候,将此时的string append到list里去,并且注意一定要返回!因为valid排列不只一个
  • 如果没有if right < left: return, 就会出现很多‘)(’这种组合,因为valid排列总是先左后右的,所以做这种检查,不然就会先右后左
  • 动态规划解法:
    https://discuss.leetcode.com/topic/28374/clean-python-dp-solution

38. Count and Say

题目说的实在是太不明白了。。。
解释一下就是,输入n,那么我就打出第n行的字符串。
怎么确定第n行字符串呢?他的这个是有规律的。
n = 1时,打印一个1。
n = 2时,看n=1那一行,念:1个1,所以打印:11。
n = 3时,看n=2那一行,念:2个1,所以打印:21。
n = 4时,看n=3那一行,念:一个2一个1,所以打印:1211。
以此类推。(注意这里n是从1开始的)
所以构建当前行的字符串要依据上一行的字符串。“小陷阱就是跑完循环之后记得把最后一个字符也加上,因为之前只是计数而已。”

其实就是对上一个字符串进行统计计数,需要注意的地方有:

  • 要将temp, pivot, count的初始化写字for循环里边,for循环总共循环n-1次,因为当n=1时,res = '1'. temp应该定义为空字符串,而不是空数组
  • 共两个for循环,外层控制循环次数,内层控制遍历统计上一个字符串的字符。当char != pivot时,我们已经完成了对char的计数,就将temp += str(count) + pivot添加到字符串里,并对pivot进行更新,同时将新的count设置为1.
  • 当内层for循环结束后,还要将统计结果再一次添加到temp中temp += str(count) + pivot,这是因为内层循环结束后最后一个字符还尚未添加进去
  • 在每次内层循环结束后,更新resres = temp

43. Multiply Strings

  • 先初始化一个用来存放结果数字的数组,数组的长度为
    res = [0]*(len(num1) + len(num2)), 两个数组相乘的位数是小于他们的位数之和的,注意是位数之和,而不是相加后的位数。
  • 内层for循环结束后,digit要减1,这是因为计算相乘时,将分别相乘的和加起来时,是要向后错位的,自己在纸上写一下计算过程就知道了。
  • 每次内层循环也要cur - 1,也是因为每单次计算结果时也是从后往前得出结果的
  • for 循环时,一定要是for int1 in reversed(num1),reversed很重要,千万不能忘
  • 内层for循环,在计算两个数的真正成绩,和进位数字的时候,一定要是'+=', res[inner] += int(int1) * int(int2),
    res[inner - 1] = res[inner] / 10. 相乘时不要忘了类型转换
  • 最后要将res数组前边的0pop掉,然后当res数组不为空时,返回join结果,如果为空,就返回‘0’
  • ' '.join(map(str, res)): map(str, res)是将List数组中的每个元素转换为str类型,并去掉list结构。' ' .join()就是将他们连接起来成为一个字符串

67. Add Binary

用到的和43题类似的方法,初始化一个数组,然后一位一位的相加,最后将数组再转换为字符串。需要注意几个地方:

  • 执行完a.zfill(l2)等语句之后,要将之后用到的len更新,不能再使用旧的lenth符号
  • 相乘那道题用的是两层for循环,这道题只需要一个while循环,因为相加是每位都对照的
  • 最后也要检查res数组在res.pop(0)之后是否长度为0,若为0 就直接返回‘0’, 若不为0,再用join, map方法将数组转换为字符串输出

71. Simplify Path

费了半天力气,原来根本没有理解透题意,因为对Unix的路径含义不是很清楚。简单来说就是,.意味着当前文件夹,..意味着parent folder

对于每一个块(以‘/’作为分界)进行分析,如果遇到‘../’则表示要上一层,那么就是进行出栈操作,如果遇到‘./’则是停留当前,直接跳过,其他文件路径则直接进栈即可

  • 先将path以'/'字符进行split,此时得到的是数组形式的结果,然后对数组进行解析,将值为空或者为.的元素去掉。然后初始化一个空数组stack
  • 对数组中的每个元素进行遍历,如果元素值为..,就意味着要返回上一层,我们就从stack中pop出来一个元素,注意要检查stack是否为空
  • 若元素值不为..,我们就将元素append到stack中。
  • 最后返回'/' + '/'.join(stack), 不要忘了最头端的'/', 并且再用'/'把stack中的元素连接起来

93. Restore IP Addresses

实现中需要一个判断数字是否为合法ip地址的一项的函数,首先要在0-255之间,其次前面字符不能是0。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,712评论 0 33
  • 过年期间,笔者实在无聊,而且年后要找关于数据方面的实习,就用了大概3天空闲时间二刷了leetcode的string...
    handSomeJoe阅读 1,044评论 0 1
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,504评论 18 399
  • 一直由着自己的性子看书,读书笔记做的又不够,太懒,还是要克服自己的惰性。 做一件事情总是不停的扩展,好多时候就失去...
    九溪蛮阅读 204评论 0 0
  • 时间过去 记忆沉没 像那艘太平轮 列车飞驰 穿过原野 将我的回忆带到远方 把我的思念 化作未完成的旋律 把我的思念...
    渔阳鼙鼓阅读 235评论 1 2