Leetcode刷题(Week5)——字符串专题

刷题时间: 2019/04/08 – 2019/04/13
主播:yxc(闫学灿)
视频链接:https://www.bilibili.com/video/av35164027?from=search&seid=5284571979100115908

题号题目链接
93Restore IP Addresseshttps://leetcode.com/problems/restore-ip-addresses/
43Multiply Stringshttps://leetcode.com/problems/multiply-strings/
49Group Anagramshttps://leetcode.com/problems/group-anagrams/
151Reverse Words in a Stringhttps://leetcode.com/problems/reverse-words-in-a-string/
165Compare Version Numbershttps://leetcode.com/problems/compare-version-numbers/
5Longest Palindromic Substringhttps://leetcode.com/problems/longest-palindromic-substring/
3Longest Substring Without Repeating Charactershttps://leetcode.com/problems/longest-substring-without-repeating-characters/
131Palindrome Partitioninghttps://leetcode.com/problems/palindrome-partitioning/
227Basic Calculator IIhttps://leetcode.com/problems/basic-calculator-ii/
224Basic Calculatorhttps://leetcode.com/problems/basic-calculator/
647Palindromic Substringshttps://leetcode.com/problems/palindromic-substrings/
438Find All Anagrams in a Stringhttps://leetcode.com/problems/find-all-anagrams-in-a-string/
8String to Integer (atoi)https://leetcode.com/problems/string-to-integer-atoi/
125Valid Palindromehttps://leetcode.com/problems/valid-palindrome/

解题心得

No.93 打印所有合法的IP (AC)

  • 首先特判字符串长度小于4和大于12的不合法情况;
  • 每个字段后面加‘.’,最后添加到答案中是,去掉最后一个’.’。
  • 需要特判不合法的写法,如01.00.010.10,含多余的0的也是不合法的表达,去掉。
  • 深度递归来做。

No.43 字符串乘法 (AC)

  • 题意:两个超大的数用字符串表示,求他们的成绩。
  • 此题先要放弃转换成整数之后再求解的方法,直接模拟竖式计算。
  • 先计算按位乘法,将中间结果以string的形式存在vector数组中,然后对所有的中间结果做加法计算。
  • 有几点容易出错:
  1. int tmp = p % 10 + up; s.insert(0, to_string(tmp % 10)); // tmp有可能还超过10,需要再对10取模
  2. int l = pool[j].size(); if (l > i){ sum += (pool[j][l - i - 1] - '0') ; // 只有当长度够的时候才参与运算 }

No.49 把单词组成字母相同的分为一组(AC)

  • 哈希表来做 unordered_map<string, vector<string> > hash;
  • 把每个单词按照字典序排序 string s; sort(s.begin(), e.end());
  • 然后把字典序排序相同的放到同一个hash值对应的vector< string >
  • 遍历哈希表 for(auto group : hash), 将哈希值中对应的全部string放到结果中res.push_back(group.second);

No.151 翻转字符串,并保持单词内部顺序不变(AC)

  • 翻转两次,第一次翻转整个句子,第二次翻转每个单词
  • string整个句子翻转直接用reverse(s.begin(), s.end()); 单词内部翻转用reverse(s.begin() +i, s.begin() + j);i,j分别指向单词的第一个和最后一个字符。
  • 题目还要求删除多余空格,用s.erase(s.begin() + i);
  • 需要注意的是,除最外层循环需要判断j < len && s[j] != '\0',如果漏掉j < len,会导致无法跳出循环 ;初始设置i = j = 0,那么初始判断是应保证i <= j,若没有 =,则循环无法进入。
  • 最后一个单词翻转可能会有一盒对于空格,需特判一下。删除用s.erase(s.begin() + s.size() - 1), s.erase(s.end() - 1)是不对的!

No.165 判断版本号是否相同(AC)

  • 可以把版本号(string)转换成一个vector<int>数组
  • vector<int>可以直接比较,比较的时候是按照字典序比价的。vector<int> v1; vector<int> v2; if(v1 > v2) ...;

No. 5 求最长回文子串(AC)

  • 仍然按照加‘#’的方法解决就问题,代码中需要考虑的边界条件比较多,很容易写溢出。
  • 直接分奇偶两种情况来算最长的长度,这种方法写起来更简洁。

No.3 求最长无重复字符的子串(AC)

  • 直接枚举,两层循环

No.131 回文子串划分(待完成!)

  • 。。。TODO。。。

No. 227 多项式计算(不包含括号)(AC)

  • 需要用栈来做
  • 两个栈,一个存储数字,一个存储运算符
  • 在实现的时候有一些技巧。按照自己的方法来实现,思路不清晰,且容易出错,详见链接。参考yxc代码,每一次循环的时候,只有碰到数字,采取判断要不要执行运算,这样很好避免了运算符后面没有数字的情况。但也有边界情况需要判定,当数字栈中只有一个元素,且符号栈中没有元素时,不能直接访问ops.top()。
  • 空格字符需要过滤
  • 当符号站中是两个加减符号时,自己写的方式是计算后两个数的加减运算,这样会导致最后有一步加减运算无法被执行。yxc的代码中原则的是计算前两个数的加减运算,再把另一次加减运算压入栈。
  • 要有一个实现的小技巧,为了保证多项式中每一步都能被执行,在多像是末尾加上“+0”。
  • 枚举指针要及时更新
  • 把string转换成数字。atoi(s.substr(i, j - i).c_str())atoi()需要传入char*,因此string在传入之前还要进行一下转化s.c_str().

No.224 含括号的加减运算(AC)

  • 同上,用两个栈分别存储数字和运算符。
  • 不需要在字符串后面“+0”
  • 当前指向的字符为 ‘)’ 时需要特殊处理。和 ‘)’ 挨着的一定是 ‘(’ ,因此先将它弹出来,弹出来之后再判断栈中是否还有 ‘+’ / ‘-’ 运算符,如果有,进行计算。
  • 最后返回数字栈栈顶元素
  • 这类题目需要多分析几个样例,找到模拟规律,不然容易漏掉某些处理
  • 由于只有加减运算,因此可以从前往后过滤掉括号,直接按顺序计算。

No.647 求字符串中回文子串的数目 (AC) (划重点)

  • 本题可以用两种方法来做,分别是中心拓展法和字符串哈希。
  • 中心扩展法会遇到的一个问题是有奇偶两种情况需要分别考虑。这里不能采取加‘#’将所有情况转换成奇数的策略,这样会直接影响结果,需要奇偶分开讨论。
  • 字符串哈希算法有几个需要注意的点,首先需要记录正序和逆序的前缀哈希值;其次,哈希值一般是采用下标从1–len, 因此在 计算哈希值时需要特别要注意一下;在计算某个字符串的哈希值时,也要特别注意下标,由于前缀哈希值的下标是从1–len, 因此,若不对应,容易溢出。

No.438 Find All Anagrams in a String (TLE)(划重点)

  • TLE思路: 将字符串按字典序排序,判断是否相等。超时

No.8 将字符串转换成数字 (AC)

  • 考虑到各种边界情况(如超出int范围的数据,sum可以定义为long类型)
  • 用一个symbol变量记录数字的符号
  • 用flag变量就是否已经开始计数
  • 返回答案是记得sum * symbol

No. 判断一个含无效字符的字符串是否为回文串 (AC)

  • 方法一,遍历去掉无效字符后,将结果字符串翻转,比较反转前后的字符串是否相等。
  • 方法一的做法时间效率不高
  • 用线性扫描的方法优化,双指针实现。
  • 需要注意的是,如何判断前后两个字符可以等效。当时大写字母和数字的组合时,直接用abs(s[i] - s[j]) == 32;判断会出Bug,还需要加上is_character(s[i]) && is_character(s[j])的限制条件。

附:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值