字符串
是
baixiaofei567
如果十年前没种树,那最好的时间是现在
展开
-
1190. 反转每对括号间的子串
一开始看到这题就感觉用递归or栈做,递归版本可能太久没写了,是不对的,还是向栈妥协了。栈中记录的是左括号的下标,当你碰到右括号的时候,将栈顶的左括号和其匹配并出栈,将这两个下标之间的字符串全部翻转,不包括(),包括也没事。最后再遍历tmp之后将其取出()就行了class Solution {public: string reverseParentheses(string s) { //递归翻转,写个函数,碰到(就进入,碰到)就退出 //将前面翻转好的,加上后..原创 2021-05-26 23:41:55 · 200 阅读 · 0 评论 -
大数加法
不难,不管是数组,还是字符串,就用这个模板,不用考虑最后的进位什么的,也不用考虑越界什么的。但是sum是%10得来的,carry是/10得来的别搞反了。class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算两个数之和 * @param s string字符串 表示第一个整数 * @param t string字符串 表示第二个整数 * @return st.原创 2021-04-14 00:26:26 · 143 阅读 · 0 评论 -
1143. 最长公共子序列
这种题目是真正的好题。二维dp不难,难的是状压dp,记录左上的是细节,细节中的细节class Solution {public: int longestCommonSubsequence(string text1, string text2) { //字符串子序列也就是匹配问题就考虑二维dp或者滑动窗口 //滑动窗口不能确保顺序,还是得dp //状态定义:dp[i][j]代表1的前i位和2的前j位最长的匹配长度 //状态转移:多种.原创 2021-04-05 02:02:11 · 136 阅读 · 0 评论 -
318. 最大单词长度乘积
没啥好说的注意两个点,string的find是用来找子串的,也就是string,不是用来找char的,乖乖用substr截取一个字符串。string的find找到的话返回的是第一个匹配的下标,找不到的话是这个字符串.npos这个东西,不是返回迭代器的class Solution {public: int maxProduct(vector<string>& words) { //普通的暴力做法 //直接string的find来找就完事了.原创 2021-04-04 01:20:46 · 155 阅读 · 0 评论 -
696. 计数二进制子串
比较巧妙的简单题。两种方法,空复分别是O(n)和O(1)法一:先用一个数组计算连续出现0或1的每组的个数,比如00111就是23,那么它们就能组成两对法二:其实只需要考虑前一组连续出现的数字的长度就行了,最后还要加上min(preSum,tmp),因为可能会有0011这样的,那么最后更新了tmp=2就没有加上,那就不行!class Solution {public: int countBinarySubstrings(string s) { //先用一个数组计算连续出现0或.原创 2021-03-29 01:13:25 · 69 阅读 · 0 评论 -
9. 回文数
int越界,直接上string和reverseclass Solution {public: bool isPalindrome(int x) { //负数直接false if(x < 0) return false; //用一个数来接住reverse的x,或者两个string解决 string tmp = to_string(x); string tmp1 = tmp; reverse(tm.原创 2021-03-28 01:16:37 · 98 阅读 · 0 评论 -
205. 同构字符串
映射关系,无脑哈希,就是记录每个字符对应映射到的另一个是什么字符。比如abba和cddx,那么a记录下映射的c,后面居然要重新映射到x,证明是错的。要映射两次,比如cddx和abba,这样的情况,就不只是考虑s映射到t,还有t映射到sclass Solution {public: bool isIsomorphic(string s, string t) { //映射考虑哈希 //用unordered_map<char,char>,ma[e] = .原创 2021-03-28 01:15:07 · 74 阅读 · 0 评论 -
409. 最长回文串
也是挺巧妙的题目,我以为是找s的最长回文串,没想到是把s组成最大的回文串。不看答案我想不出,毕竟最近有点笨,哈希表记录每个字符的出现次数。因为是回文串,所以有aba和abba这两种,出现次数是偶数次的一定可以全部拿来贡献回文串,奇数次的-1可以用来贡献。而且因为有aba这种,所以如果有出现奇数次的,最后最大长度还得要加上1class Solution {public: int longestPalindrome(string s) { //用哈希记录每个字符出现的次数 .原创 2021-03-28 01:12:31 · 69 阅读 · 0 评论 -
242. 有效的字母异位词
哈希解决,一个+一个-,最后遍历key,如果有不为0的就是falseclass Solution {public: bool isAnagram(string s, string t) { //如果相等就不是异位 if(s.length() != t.length()) return false; //用哈希记录就行了,s的+,t的-,最后遍历key,如果有不等于0的就false //第二种方法就是直接上sort然后直接比较就行了.原创 2021-03-28 01:09:37 · 53 阅读 · 0 评论 -
151. 翻转字符串里的单词
两种方法,用stack和不用stack,很简单的题,注意几个细节即可1.注意前驱空格,需要全部省略,所以当前为空格且tmp字符串为空时,跳过当前空格。如果tmp不为空,就加入栈或者直接加在res前面2.s结尾不一定有空格,所以最后可能还有一个字符串没有加入。3.如果不是用栈的话,又没有特殊处理,最后必定有一个空格,直接substr处理掉最后一个class Solution {public: string reverseWords(string s) { //先借助stac.原创 2021-03-11 02:02:05 · 51 阅读 · 0 评论 -
415. 字符串相加
就是大整数相加,从后往前加,只要有一个字符串没遍历完就要继续,如果还有carry也要继续最后将res反转即可class Solution {public: string addStrings(string num1, string num2) { //就是大整数相加,从后往前加,只要有一个字符串没遍历完就要继续,如果还有carry也要继续 //最后将res反转即可 string res = ""; int len1 = num1.原创 2021-03-06 02:19:42 · 105 阅读 · 0 评论 -
583. 两个字符串的删除操作
编辑距离的easyeasy版本,说到底就是求最长公共子序列,最长公共子序列当然是二维dp啦状态定义:dp[i][j]表示的是取1的前i位和2的前j位的最长公共序列状态转移:当word[1]==word[2]的时候,dp[i][j]等于dp[i-1][j-1]+1,打个比方就是abc和bbc,那么c相等的情况下就是求ab和bb的最长公共子序列然后加上这个c如果不相等,就继承dp[i-1][j]和dp[i][j-1]中较大的那个basecase:就是长度都为0的时候公共序列长度为0最后返回两个长度相.原创 2021-03-04 01:24:36 · 74 阅读 · 1 评论 -
763. 划分字母区间
身体不适,时复和空复差点算了。滑动窗口那味,每增加一个就将window中出现该字符的次数+1,然后遍历window,如果window中的字符和need的都一样,就将tmpLen加入res,然后重置tmpLenclass Solution {public: vector<int> partitionLabels(string S) { //要划分出尽可能多的片段 vector<int> res; //要让片段中的所有字符只.原创 2021-02-20 01:43:29 · 62 阅读 · 0 评论 -
392. 判断子序列
暴力遍历t就行了,准确的说是双指针,如果s走到头了就可以了,如果t先走到头,就是falseclass Solution {public: bool isSubsequence(string s, string t) { //不能用滑动窗口,就暴力遍历 //当遍历完t就结束了 if(s.length() > t.length()) return false; if(s == t) return true; in.原创 2021-02-20 01:38:03 · 64 阅读 · 0 评论 -
451. 根据字符出现频率排序
堆排就是击败5%。这些和出现次数有关的还是得用桶排序效率比较高。就是根据出现次数最多的max开一个二维数组,二维数组的大小是max+1。这样我们就可以按照出现次数将对应的数字放入那个桶中,然后从大到小遍历所有桶即可。class Solution {public: // struct cmp{ // bool operator()(const pair<char,int>& a, const pair<char,int>& b){ .原创 2021-02-19 02:03:14 · 106 阅读 · 0 评论 -
524. 通过删除字母匹配到字典里最长单词
双指针,一个指针在s上走,一个指针在字典里的每个字符串上走。走完判断r是否和字典里的这个字符串的长度相等,如果相等就可以试试看用这个字符串来更新res。字典序比较小的意思是aa<ab,所以要用d[i]和res比一下谁更小,d[i]更小就行了先比长度,如果长度一样再比字典如果不想写这么多if-else也可以先对字典进行排序,这样子字典序小的就在前面,我们只要判断长度是否大于res就可以更新了class Solution {public: string findLongestWord(.原创 2021-02-18 01:10:47 · 139 阅读 · 0 评论 -
395. 至少有K个重复字符的最长子串
今天做的最难的一道题(菜),一开始想要滑动窗口,不过估计做不出。所以用了递归分治,每次判断该字符串的字符是否都大于k次,就要每次都开一个哈希表,用数组记录就行。用一个i遍历字符串,用while,记得判断越界操作,直到找到第一个小于k的或者越界就退出。如果是因为越界退出的,证明s中没有小于k的,返回整个s。如果不是,证明s[i]这个字符出现次数小于k,我们计算它左边的复合要求的子串长度,用s.substr(0,i)即可。此时因为s[i]是不符合要求的,而s[i]又是重复出现的,我们用while跳过这些小.原创 2021-02-18 00:53:54 · 320 阅读 · 1 评论 -
131. 分割回文串
dfs加回文串的easy题。如果当前的子串是回文串,就有两种情况,在这里切一刀,往后继续找,或者带着自身这个回文串继续往后找。递归边界就是index走到字符串的最后一位,而且加上最后一位的tmp是回文串,就让tmp数组加入这个回文串,然后res加入tmp数组class Solution {public: bool isPalind(string s){ string tmp = s; reverse(tmp.begin(),tmp.end()); .原创 2021-02-08 01:31:50 · 119 阅读 · 0 评论 -
127. 单词接龙
好题好题,题解都在代码注释里了class Solution {public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { //主要是将begin、end和字典中的所有字符串形成一张图,无向图,因为可以互相转换 //仅有一个字符不同的字符串可以互相转换 //建完图后,用bfs找单源最短路径,这里我们边建图边找 ..原创 2021-02-07 01:00:47 · 95 阅读 · 0 评论 -
125. 验证回文串
可以reverse也可以双指针,双指针不停走的时候,必须时刻判断是否越界了。class Solution {public: bool isPalindrome(string s) { //回文串就是中心扩散,有一个中心和两个中心 if(s.length() == 0) return true; //只考虑字母和数字,不考虑大小写,不考虑空格和标点 //肯定不让你用额外容量,vector肯定不用说,string+=可以 .原创 2021-02-07 00:59:49 · 74 阅读 · 0 评论 -
44. 通配符匹配
和正则表达式差不多,记得初始化很重要。class Solution {public: bool isMatch(string s, string p) { //?不能匹配空,*可以匹配空,就是不匹配任何东西 //说到底就是kmp,直接二维dp解决 int sLen = s.length(), pLen = p.length(); //dp[i][j]表示的是p的前j位可以正常表示s的前i位 vector<v..原创 2021-02-03 01:13:56 · 184 阅读 · 0 评论 -
38. 外观数列
pat的老题目了,每一轮新定义一个tmp,在一轮结束后将其赋给res。遍历res,每遍历一个字符,cnt都重置为1,c为当前字符,如果下一个字符和c相等,就让cnt++,j也++,这样就可以跳过这些被扫描过的字符了。无论跳不跳,此时的res[j]和res[j+1]不相等,所以不用再对j做别的操作。让tmp加上cnt+‘0’。再加上cclass Solution {public: string countAndSay(int n) { //pat真题,每一项都是前一项的描述...原创 2021-02-03 01:09:55 · 68 阅读 · 0 评论 -
28. 实现 strStr()
妥妥的滑动窗口,收缩到cnt不满足need.size()class Solution {public: int strStr(string haystack, string needle) { //首先要判断是否有这个才行,滑动窗口判断即可 //在窗口里的东西都满足后判断needle和窗口是否相等,如果相等就返回left if(haystack.length() < needle.length()) return -1; i.原创 2021-02-02 01:33:01 · 90 阅读 · 0 评论 -
14. 最长公共前缀
暴力法,外层是遍历的位数,内层是遍历所有字符串,char c记录第一个字符串的当前位,如果后面有一个字符串的当前位不是c或者当前长度已经大于被遍历的某个字符串,都要退出,并且要退出大循环,用一个flag记录。如果一轮下来都是相同的,就让结果+=cclass Solution {public: string longestCommonPrefix(vector<string>& strs) { //来一个hash记录每个字符出现的次数肯定不行,有些字符在一个字.原创 2021-02-02 01:19:54 · 81 阅读 · 0 评论 -
13. 罗马数字转整数
模拟题,将罗马数字转为int类型大的放左边,IVIX,XLXC,CDCM是在特殊情况,别的只要+上对应的就行了不会有IIV这种,只会有IV这种,所以只要考虑小的后一位是不是大于自己就行了,记得判断是否越界class Solution {public: int romanToInt(string s) { //模拟题,将罗马数字转为int类型 //大的放左边,IVIX,XLXC,CDCM是在特殊情况,别的只要+上对应的就行了 //不会有II...原创 2021-02-02 01:17:07 · 119 阅读 · 0 评论 -
647. 回文子串
又是回文子串,中心扩散法必须记住!!中心扩散法的特点是可能有1个中心or两个中心。在遍历的时候两个中心的情况也要考虑!!这就是中心扩散法的模板class Solution {public: int countSubstrings(string s) { //计算有几个回文子串,dfs? //之前有最长回文子串,是用中心扩散的,为什么回文子串是中心扩散??两个也可以形成回文子串啊 //中心可能一个点or两个点 int res = 0.原创 2021-01-31 01:42:37 · 63 阅读 · 0 评论 -
567. 字符串的排列
长度不满足时收缩。class Solution {public: bool checkInclusion(string s1, string s2) { //要在字符串中搜索子集问题,或者排列之类的问题,如果可以通过双层循环解决,一定可以通过滑动窗口解决 //这tm比最短更简单!!只要valid等于need.size直接返回就行了 if(s1.length() > s2.length()) return false; un.原创 2021-01-30 01:22:21 · 97 阅读 · 1 评论 -
438. 找到字符串中所有字母异位词
滑动窗口典型题,重要的就是搞清楚left收缩那个地方,什么时候要收缩,什么时候缩完了。有些时候是长度不满足要求了,有些时候是window里面的字符不满足要求了,就收缩结束了。class Solution {public: vector<int> findAnagrams(string s, string p) { //hash+滑动窗口 vector<int> res; if(s.length() < p.leng..原创 2021-01-30 01:19:37 · 103 阅读 · 0 评论 -
394. 字符串解码
字符串搜索问题,妥妥的递归,但是挺复杂的。index必须传引用!这样在下一层遍历完[]里的字符后,就可以直接跳过[]这个了class Solution {public: string dfs(string& s, int& index){ string res = ""; int count = 0; for(;index < s.length(); ++index){ //计算[前的数字 ..原创 2021-01-30 01:09:12 · 64 阅读 · 0 评论 -
139. 单词拆分
不是chineseCode就是dpCode。看题才是真的麻烦法一:超时的dfs,搜索的题目不是dfs就是dp。此处的dfs的参数有当前遍历到的字符串的下标,如果遍历到字符串结尾就返回true。在dfs内部从index遍历到字符串末尾,如果从index到i这个字符串在字典中有,就遍历剩下的字符串。如果一直从index到结尾都找不到,就返回false,相当于回溯。回到上一层找别的情况。法二:dp,此处的dp[i]表示的是前i个字符串是否都能被正常表示,dp[0]等于true,因为0个字符一定能正常被表示。.原创 2021-01-28 00:58:29 · 160 阅读 · 0 评论 -
22. 括号生成
就是一个dfs的过程,取或者不取,我们用两个值分别记录左右括号的数量,一开始都设为0,这里的回溯是自动回溯,如果是对tmp传引用的话就要弹出当前最后一位。如果是传参当return后,tmp回归到上一状态。dfs内部如果左右括号的数量都等于n,就将tmp加入结果数组,并return。如果左边的数量<n,就递归搜索,参数就是left+1,right不变,tmp就是tmp加上"("。如果right不等于n并且right的数量严格小于left,就dfs右边的括号,必须严格小于,等于都不行class Sol.原创 2021-01-19 01:36:52 · 71 阅读 · 0 评论 -
20. 有效的括号
这道题就是一个括号匹配的问题,如果遍历到右半部分的符号,而前面最新的一个左半部分的符号不匹配,那就是无效的。所以我们要记录最新的括号,就要用一个先进后出的数据结构来记录左边的括号,就是栈!当s的长度为奇数直接false。遍历字符串,如果是左半部分的符号就加入栈,如果是右边的就判断栈是否空(必须要加),不加会报错,如果空就返回false,如果右半部分为’]",而栈顶不是’[’,那就是false,如果匹配,就弹出栈顶元素。其他以此类推,最后返回栈是否为空,如果为空就证明匹配完了,如果不为空,证明没匹配干净,..原创 2021-01-18 01:42:42 · 114 阅读 · 0 评论 -
17. 电话号码的字母组合
一看就是dfs,其实算是比较简单的dfs了,我居然还做不出,我真是个sb。来一个index记录当前遍历到给定字符串的哪一位即可。在dfs里,如果遍历到最后一位了,就将临时字符串加入结果数组。如果没有,就遍历当前字符串中的数字对应的所有的字母,用一个vector来存即可,循环中将tmp+上当前数字的对应字母,然后对其dfs,并将index+1,遍历完后回溯,就是将tmp最后一个字符删掉,用erase(tmp.end()-1)即可,因为end()迭代器是最后一位的后一位,不指向任何字符。class Solu.原创 2021-01-16 02:59:05 · 167 阅读 · 0 评论 -
10. 正则表达式匹配
牛客的递归超时了,要用dp。这里也是二维dp,二维dp=填表。字符串好多都是用二维dp,这里是记录两个字符串的位置,回文子串是记录首尾下标。class Solution {public: /*bool matchCore(string s, string p, int sIndex,int pIndex){ //如果两者同时走到结尾就是true if(s.length() == sIndex && p.length() == pIndex) ..原创 2021-01-16 02:49:12 · 371 阅读 · 0 评论 -
5. 最长回文子串
三种方法1.暴力通过剪枝可以达到O(n^2)的时复2.二维dp,此处需要用到二维dp,dp[i][j]存的是以i为头,j为首的字符串是否为回文串。根据回文串的性质来写转移方程。1.回文串两头相等。2.回文串去掉头尾还是回文串。我们用maxLen和begin来记录子串的起始位置和最大长度,不要每次都substr。因为这里是二维dp,二维dp最最重要的就是填表顺序,这里我的填表方式是一列一列填表,因为dp[i][j]要根据dp[i+1][j-1]来推断,刚好是左下角,所以一列一列填表是可以,而且只要填右上.原创 2021-01-16 02:42:28 · 124 阅读 · 0 评论 -
297. 二叉树的序列化与反序列化
一顿操作猛如虎,一看超过5%两个操作都是dfs(前序遍历),序列化操作:因为是先序(根左右),所以先对根进行操作,如果为空就将字符串加上#并返回,因为要改变原字符串,所以传入的字符串是引用。如果不为空,就将string加上该结点值的字符串形式再加上’,’,然后递归左子树和右子树。反序列化操作:定义一个空结点,也是传引用,因为要改变自身的值,再传入输入的字符串和下标,因为不是char类型的字符串,所以不能通过++来取下一个要用下标取,所以index传的也是引用。如果index等于最后一位就return,.原创 2021-01-14 01:18:12 · 127 阅读 · 1 评论 -
剑指offer——序列化二叉树C++
/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Solution {public: //二叉树=递归||栈||队列 char* Serialize(TreeNode *root) { .原创 2021-01-06 02:08:43 · 184 阅读 · 0 评论 -
剑指offer——字符流中第一个不重复的字符C++
直接图方便了,来一个string和一个map,每次insert就加在s后面,并记录该字符出现次数。在first函数中,遍历该字符,找到第一个出现一次的返回即可。class Solution{public: //Insert one char from stringstream void Insert(char ch) { s += ch; ma[ch]++; } //return the first appearence once .原创 2021-01-05 02:06:00 · 201 阅读 · 1 评论 -
剑指offer——正则表达式匹配C++
难点有21:理清思路很难。2:"“的匹配有很多情况不知道到底是匹配几个很难。这里我们用的是递归求解。分情况:先看pat的下一个是否为” * “,如果是,那么又有两种情况,当前位是否匹配,如果当前位匹配(可以用两个字符串当前字符相等或者pat当前字符为”.“来判断),那么要看接下来这个”“到底要匹配多少次了。第一种情况aa和aaa,匹配0次;第二种情况aa和aa,匹配1次;第三种情况aaab和a*b匹配多次。所以我们递归判断每一种情况,只要有一种为true,那么就是true,用||运算符。匹配0次是st.原创 2021-01-05 02:04:03 · 253 阅读 · 0 评论 -
剑指offer——把字符串转换成整数C++
不难,先记录第一位是否是+or-,设置flag。然后反向遍历字符串,如果不是合法字符,就return0,如果是,就让res+=这一位*pow(10,length-i-1),最后一位是个位就×pow(10,0)class Solution {public: int StrToInt(string str) { //从后往前遍历到第1位,第0位不要,如果遍历到非法字符,直接返回0 //用pow(10,lenght-1-i)*当前位即可 int re..原创 2021-01-04 02:09:27 · 213 阅读 · 0 评论