字符串专场

459. 重复的子字符串

1…给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:输入: "abab"输出: True解释: 可由子字符串 "ab" 重复两次构成。
示例 2:输入: "aba"输出: False
示例 3:输入: "abcabcabcabc"输出: True解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。
## 思路
1. 先拿到所有可能满足的子串(能被整除的,这样重复才能构成一个完整的字符串)
2. 拿可能的子串然后以子串的长度为步长循环判断后面+步长的子串是否满足,只要有一个不行就不行class Solution {public boolean repeatedSubstringPattern(String s) {for(int i=1;i<s.length();++i){if(s.length()%i==0){   //先找到所有可以被字符串整除的子串,只有这些才有可能组成完整的String t=s.substring(0,i);  //截取出来比如sasa,会先拿一个s,然后不等就拿saboolean flag=true;for(int j=i;j+i<=s.length();j+=i){  //步长为2if(!t.equals(s.substring(j,j+i))){//sa等于后面多2长度的sa相等的就不处理flag=false;break;}}if(flag) return true;}}return false;}
}

383. 赎金信

给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false

(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)

注意:

你可以假设两个字符串均只含有小写字母。

canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
## 思路
1. 如果magazine的长度比ransom还短,那根本不行,因为要求的是magazine中的字符能构成ransom,而且每个字符只能用一次
2. 遍历ransom所有字母,去magazine中去找,利用了一个26个字母的计数数组,如果找到了就在它对应数组计数+1,然后下次找的话就会因为是从下标开始,下标加一了,下次会跳过这个已经匹配的字母了
3. 只要有一次没匹配成功返回了-1就说明ransom中有字母在magazine中找不到了int indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。class Solution {public boolean canConstruct(String ransom, String magazine) {if (magazine.length() < ransom.length()) return false;int caps[] = new int[26];for (char c : ransom.toCharArray()) {int index = magazine.indexOf(c, caps[c - 'a']);if (index == -1)return false;caps[c - 97] = index + 1;}return true;}
}

387. 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例:

s = "leetcode"
返回 0s = "loveleetcode"
返回 2
## 思路
1. 类似计数器,利用数组计数
2. 遍历一次再找到第一个值为1的,时间为2N=O(N)
class Solution {public int firstUniqChar(String s) {int[] chars = new int[256];for(int i=0;i<s.length();i++){chars[s.charAt(i)]=chars[s.charAt(i)]+1;}//遍历字母在数组中的值第一个等于1的就是第一个唯一的for(int i=0;i<s.length();i++){if(chars[s.charAt(i)]==1){return i;}}return -1;}
}

551. 学生出勤记录 I

给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符:

  1. ’A’ : Absent,缺勤
  2. ’L’ : Late,迟到
  3. ’P’ : Present,到场

如果一个学生的出勤记录中不超过一个’A’(缺勤)并且不超过两个连续的’L’(迟到),那么这个学生会被奖赏。

你需要根据这个学生的出勤记录判断他是否会被奖赏。

示例 1:

输入: "PPALLP"
输出: True

示例 2:

输入: "PPALLL"
输出: False
## 思路
1. 本题较为简单,看代码即可读懂
public class Solution {public boolean checkRecord(String s) {int countA = 0; //计数器Afor (int i = 0; i < s.length() && countA < 2; i++) { //A超过2也就没奖赏了没必要下去执行了if (s.charAt(i) == 'A')countA++;//如果在最后三个字符前有三个连续的三个L那就也没奖赏了if (i <= s.length() - 3 && s.charAt(i) == 'L' && s.charAt(i + 1) == 'L' && s.charAt(i + 2) == 'L')return false;}return countA < 2;}
}

541. 反转字符串 II

给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。

示例:

输入: s = "abcdefg", k = 2
输出: "bacdfeg"
## 思路
1. 拿到字符数组,然后开始遍历,因为他是每隔2k个字母然后前k个进行反转,那么步长为2k
2. 左右指针,左右交换有点像快速排序
3. 剩余字符少于 `k` 个,则将剩余字符全部反转,所以如果到数组上限了要做处理class Solution {public String reverseStr(String s, int k) {char[] chars = s.toCharArray();int n = chars.length;// 每2k个元素为一组进行反转for (int i = 0; i < n; i += 2 * k) {int left = i;//判断下标是否越界int right = i + k - 1 < n ? i + k - 1 : n -1;// 双指针交换while (left < right) {char temp = chars[left];chars[left++] = chars[right];chars[right--] = temp;}}return String.valueOf(chars);}
}

345. 反转字符串中的元音字母

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

输入:"hello"
输出:"holle"

示例 2:

输入:"leetcode"
输出:"leotcede"
## 思路
1. 先确定一个匹配元音库,判断元音的方法
2. 左右指针,从左边搜索到元音位置,右边也搜索到元音位置
3. 交换,指针左加右减,继续上述操作,直到指针重复class Solution {public String reverseVowels(String s) {// 先将字符串转成字符数组(方便操作)// 以上是只针对 Java 语言来说的 因为 chatAt(i) 每次都要检查是否越界 有性能消耗char[] arr = s.toCharArray();int n = arr.length;int l = 0;int r = n - 1;while (l < r) {// 从左判断如果当前元素不是元音while (l < n && !isVowel(arr[l]) ) {l++;}// 从右判断如果当前元素不是元音while (r >= 0 && !isVowel(arr[r]) ) {r--;}// 如果没有元音if (l >= r) {break;}// 交换前后的元音swap(arr, l, r);// 这里要分开写,不要写进数组里面去l++;r--;}// 最后返回的时候要转换成字符串输出return new String(arr);}private void swap(char[] arr, int a, int b) {char tmp = arr[a];arr[a] = arr[b];arr[b] = tmp;}// 判断是不是元音private boolean isVowel(char ch) {// 这里要直接用 return 语句返回,不要返回 true 或者 falsereturn ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'||ch=='A'|| ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';}
}

434. 字符串中的单词数

统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。

请注意,你可以假定字符串里不包括任何不可打印的字符。

示例:

输入: "Hello, my name is John"
输出: 5
解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。
## 思路
1. 直接分割空格为数组,然后遍历里面的数组值不为空格的值计数加一class Solution {public int countSegments(String s) {int count=0;String[] strs=s.split(" ");for(String str:strs){if(!"".equals(str))count++;}return count;}
}

443. 压缩字符串

给定一组字符,使用原地算法将其压缩。

压缩后的长度必须始终小于或等于原数组长度。

数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。

在完成原地修改输入数组后,返回数组的新长度。

进阶:
你能否仅使用O(1) 空间解决问题?

示例 1:

输入:
["a","a","b","b","c","c","c"]输出:
返回 6 ,输入数组的前 6 个字符应该是:["a","2","b","2","c","3"]说明:
"aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。

示例 2:

输入:
["a"]输出:
返回 1 ,输入数组的前 1 个字符应该是:["a"]解释:
没有任何字符串被替代。

示例 3:

输入:
["a","b","b","b","b","b","b","b","b","b","b","b","b"]输出:
返回 4 ,输入数组的前4个字符应该是:["a","b","1","2"]。解释:
由于字符 "a" 不重复,所以不会被压缩。"bbbbbbbbbbbb" 被 “b12” 替代。
注意每个数字在数组中都有它自己的位置。
## 思路
1. 利用指针往右滑动到下一个不同字母,然后记录前面的状态(首字母,重复个数)
2. 改变状态,把前面的移动到新指针的位置
3. t始终都为先记录一次首字母位置,然后改一次值,然后又是记录首字母位置class Solution {public int compress(char[] chars) {int t=0;//设置指针int i=0;while (i <chars.length && t<chars.length) {//遍历字符串//1.记录状态chars[t++]=chars[i];//取相同字符序列的首字符存下,主要是更新t的状态int temp=i;//记录相同字符序列首元素位置//2.滑动while (i<chars.length &&chars[i]==chars[t-1])i++;//i指针滑动到相同字符序列末尾的下一个位置//3.判断是否改值if(i-temp>1){//若相同字符序列长度大于1for(char c:String.valueOf(i-temp).toCharArray()){//向结果中加入相同字符序列的长度的字符形式chars[t++]=c;}}}return t;//t即为已压缩的结果的长度
}
}

67. 二进制求和

给你两个二进制字符串,返回它们的和(用二进制表示)。

输入为 非空 字符串且只包含数字 10

示例 1:

输入: a = "11", b = "1"
输出: "100"

示例 2:

输入: a = "1010", b = "1011"
输出: "10101"
## 思路
1. 先找到最长字符串,拿到两个字符串长度    计数器carry=0
2. 遍历最长的字符串,倒序遍历取字母如果为1,carry++,然后同时也取另一个字符串也这样判断,都为1那么carry就会为2,然后我们利用carry%2取余为1则说明进制之和为1和0,如果为0说明是1和1,我们可以这样追加0或1,然后利用carry/2保留进位如果只有1那就没有进位,如果2说明两个1,进制和为10,2/2进位为1
3. 这样就会形成一个倒叙追加0,1的字符串,低位在前,我们出来还需要判断carry进位器是否还有进位1,有就再加一次,然后反转高低位class Solution {public String addBinary(String a, String b) {int n = a.length(), m = b.length();if (n < m) return addBinary(b, a);  //f确保a是字符串长的int L = Math.max(n, m);  //L是最长字符串的长度StringBuilder sb = new StringBuilder();int carry = 0, j = m - 1; //j为短字符串b的最大下标//遍历长的字符串for(int i = L - 1; i > -1; --i) {if(a.charAt(i)=='1') ++carry;if(j>-1&&b.charAt(j--)=='1') ++carry;if (carry % 2 == 1) sb.append('1');else sb.append('0');  carry/=2; //清空计数器满2保留进位}if (carry == 1) sb.append('1');sb.reverse();return sb.toString();}
}

20. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

输入: "()[]{}"
输出: true

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true
## 思路
map中等待匹配的值),},],放入栈里是(,{,[
map先预存住右部分符号然后遇到左括号就放入栈里,如果遇到右括号就去栈中出栈找栈顶元素,拿栈顶元素和map的key对应的value进行匹配是否相等,不等就错误,或者栈里没元素了也说明右括号多了class Solution {public boolean isValid(String s) {if(s==null || "".equals(s)) {return true;}//用栈保存 (,[,{Stack<Character> stack = new Stack<Character>();//map中保存的是 ):(, ]:[,}:{//当遍历到 )时候就会去map中找对应的value,也就是(//再用这个value和stack弹出的元素比较,如果相等则匹配上,不等则返回false//这里也可以用数组来存,我为了简单就用map表示了HashMap<Character,Character> map = new                HashMap<Character,Character>();map.put(')','(');map.put(']','[');map.put('}','{');for(int i=0;i<s.length();i++) {char c = s.charAt(i);if(!map.containsKey(c)) {stack.add(c);//栈中放入 (,[,{} else {if(stack.size()==0) {return false;}//取出栈顶的元素Character tmp = stack.pop();if(map.get(c)!=tmp) {return false;}}}return (stack.empty()? true : false);}
}

680. 验证回文字符串 Ⅱ

给定一个非空字符串 s最多删除一个字符。判断是否能成为回文字符串。

示例 1:

输入: "aba"
输出: True

示例 2:

输入: "abca"
输出: True
解释: 你可以删除c字符。
## 思路 递归
利用左右指针前进和后退,然后不同的时候把chance-1再递归两种情况class Solution {public boolean validPalindrome(String s) {return validPalindrome(s, 0, s.length()-1, 1);
}/**** @param s 输入字符串* @param left 左指针* @param right 右指针* @param chance 删除节点的机会次数*/
private boolean validPalindrome(String s, int left, int right, int chance) {if (left > right) {return true;}if (s.charAt(left) == s.charAt(right)) {return validPalindrome(s, left + 1, right - 1, chance);} else {if (chance == 0) {return false;}return validPalindrome(s, left, right - 1, chance-1) || validPalindrome(s, left + 1, right, chance-1);}
}
}

58. 最后一个单词的长度

给定一个仅包含大小写字母和空格 ' ' 的字符串 s,返回其最后一个单词的长度。如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词。

如果不存在最后一个单词,请返回 0 。

**说明:**一个单词是指仅由字母组成、不包含任何空格字符的 最大子字符串

示例:

输入: "Hello World"
输出: 5
## 思路
本题比较简单,主要是利用空格来区分最后一个单词class Solution {public int lengthOfLastWord(String s) {int res = 0, i = s.length() - 1;while (i >= 0) {if (s.charAt(i--) != ' ') res++; // 非空则计数else if (res > 0) return res; // 为空,但之前已经计过数了}return res;
}
}

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
## 思路
1. 利用第一个字符串和第二个比较然后拿到最长公共的前缀
2. 然后拿到目前的前缀和后面比
class Solution {public String longestCommonPrefix(String[] strs) {if(strs.length<1)return "";if(strs.length==1)return strs[0];String demo=strs[0];for(int i=1;i<strs.length;i++){if(strs[i].equals(""))return "";int j=0;String s="";while(j<demo.length()&&j<strs[i].length()){if(demo.charAt(j)==strs[i].charAt(j)){s+=demo.charAt(j);if(j==demo.length()-1||j==strs[i].length()-1){demo=s;}j++;}else{demo=s;break;}}}return demo;}
}

686. 重复叠加字符串匹配

给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1。

举个例子,A = “abcd”,B = “cdabcdab”。

答案为 3, 因为 A 重复叠加三遍后为 “abcdabcdabcd”,此时 B 是其子串;A 重复叠加两遍后为"abcdabcd",B 并不是其子串。

## 思路
1. 就是利用indexOf()然后存A每次累加的次数,如果A.length超过了A+B的长度还没有说明B永远不会在里面
class Solution {public int repeatedStringMatch(String A, String B) {StringBuffer sb = new StringBuffer();String s = "";for (int i = 0; i < B.length(); i++) {s = s + A;if (s.length() >= B.length()) {if (s.indexOf(B)!=-1) {return i + 1;}if (s.length() > (A + B).length()) {return -1;}}}return -1;}
}

28. 实现 strStr()

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2

示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1
## 思路
1. 利用i指针不停找第一个字符串和第二个字符串相等的地方,然后记录下标,如果后续还相等就j++然后减去重复的几个位置,一种情况是needle字符串是haystack的子串是的话,只要遍历到第一个字符串和第二个字符串相等的地方,然后记录下标,等遍历完i指针减去j个重复字母,则为前面的下标第二种是它不是子串不符合不符合的话,那么要一直找到字母可以匹配的,直到第一个字符串走完,那么还不行的话就为-1class Solution {//双指针思想public int strStr(String haystack, String needle) {if (needle.length() == 0 || haystack.equals(needle)) return 0;int i = 0, j = 0;while (i < haystack.length()) {if (haystack.charAt(i++) == needle.charAt(j)) {j++;                    //aba2sda2d   a2d   4和2不等} else {if (j > 0) {i = i - j ;       //i=5-2=3  j=0  j = 0;}}if (j == needle.length()) {return i - j;}}return -1;}
}

125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明 本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true

示例 2:

输入: "race a car"
输出: false
## 思路
1. 左右指针头尾比较,如果不是字母或者数字就移动指针接着比,只要出现字母不等了就返回falseclass Solution {//双指针大法好,受我一拜!public boolean isPalindrome(String s) {s = s.toLowerCase();char[] chars = s.toCharArray();int left = 0, right = chars.length - 1;while (right > left) {if ((chars[left] >= '0' && chars[left] <= '9') || (chars[left] >= 'a' && chars[left] <= 'z')) {if ((chars[right] >= '0' && chars[right] <= '9') || (chars[right] >= 'a' && chars[right] <= 'z')) {if (chars[left] != chars[right]) {return false;} else {left++;right--;}} else {right--;}} else {left++;}}return true;}
}

秋招算法字符串专场leetcode(Easy十六题)相关推荐

  1. 2022秋招算法岗卷成人间地狱!高薪惹眼,招录比100:1

    「求职卷,进来了做实验也卷,卷翻天.」 有人说,2022 年秋招算法岗人间地狱. 那么,真实情况如何? 算法岗高薪惹眼 根据Talent Seer 2020 AI人才报告显示,全球AI从业者总人数约有 ...

  2. 谁说2021届秋招算法岗一定要灰飞烟灭啦?

    没错,这是一碗鸡汤,希望肝完这碗鸡汤的师弟师妹们就不要过度焦虑啦-理性上车,理性下车,希望萌新们都能遇到最适合自己的坑位 2014年末入坑AI,一路见证了AI行业的快速起飞.爆炸.焦虑和冷却. 小夕前 ...

  3. 2021届秋招算法岗真的要灰飞烟灭了吗?

    星标/置顶小屋,带你解锁 最萌最前沿的NLP.搜索与推荐技术 文 | 不拖更的夕小瑶 2014年末入坑AI,一路见证了AI行业的快速起飞.爆炸.焦虑和冷却. 小夕前几天在知乎上看到一个问题<如何 ...

  4. 知乎热榜:如何看待 2021 年秋招算法岗灰飞烟灭?

    公众号关注 "GitHubPorn" 设为 "星标",带你了解技术圈内新鲜事! 出处:https://www.zhihu.com/question/406974 ...

  5. 如何看待2021年秋招算法岗灰飞烟灭?

    仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:知乎,https://www.zhihu.com/question/406974583 编辑:深度学习与计算机视觉 18年是否值得进入,19年供 ...

  6. 如何看待【2021年秋招算法岗】灰飞烟灭?

    来自:知乎 链接:https://www.zhihu.com/question/406974583 XX Zhao 我以一个公司的面试官角度来回答一下这个问题吧. 我目前在tmd中一家的业务线上担任图 ...

  7. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  8. B站哔哩哔哩21届秋招算法岗笔试 假设货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小明使用1024元的纸币购买了一件价值为N(0<N<=1024)的商品

    哔哩哔哩21届秋招算法岗笔试 题目描述: 假设货币系统包含面值1元.4元.16元.64元共计4种硬币,以及面值1024元的纸币.现在小明使用1024元的纸币购买了一件价值为N(0<N<=1 ...

  9. 知乎热议“如何看待 2022 年秋招算法岗人间地狱”

    本文转载自IT之家 今年校招算法岗就业形势有多严峻?知乎热榜用一个词评价:"人间地狱".好家伙,去年对于该问题用的还是阳间词汇"灰飞烟灭",今年就开始唠阴间嗑了 ...

最新文章

  1. 推荐一个可以把网页背景色调成护眼色的Chrome扩展应用
  2. eclipse解决Android Library Project jar包重复导致的问题
  3. Spark入门阶段一之扫盲笔记
  4. 洛谷 1115——最大子段和(线性数据结构)
  5. 光源选型的要素有哪些?
  6. css3 下拉缩放显示定位导航
  7. 从零开始学编程(所以说英语也是零)
  8. C++实现 层次分析法(AHP)
  9. 安装Oracle 19c 的系统配置要求
  10. 差文解析 IIRC: Incremental Implicitly-Refined Classification
  11. Android的生命周期
  12. Dialog加载页面动画(Loding.....加载等待)三种方式
  13. 汉白玉产地在哪里_汉白玉产地在哪里?
  14. R_Studio(学生成绩)对数据缺失值md.pattern()、异常值分析(箱线图)
  15. 当下比较火的直销分销预订返佣模式系统软件定制开发
  16. 深信服服务器装系统,深信服新上网行为管理系统安装调试手册[1].doc.docx
  17. 微信最新授权登录 微信小程序无法弹出授权弹框 open-type getUserInfo获取不到用户信息 授权不弹框
  18. 三步实现沉浸式状态栏(即状态栏与APP同色)
  19. 最牛会计对账,不会这个Excel公式要崩溃
  20. linux下的wget命令实现断点下载

热门文章

  1. 伪标签Pseudo Label 与软标签 soft label
  2. 考研冲刺阶段的7大谣言!你中招了吗?
  3. 冰冰学习笔记:这些链表练习题,你会吗?(中)
  4. 2022年技能大赛“网络安全”(中职组)D模块电子答题卡
  5. iec104协议java_GitHub - renduy/IEC104_microgrid: iec104协议主站客户端程序,属于微电网管理系统一部分...
  6. Houdini湖边小屋-使用到的节点及VEX Fuction(更新中)
  7. c语言趣味算数游戏程序设计,非常经典的C语言趣味题目
  8. 一些简单的Linux指令
  9. 电子计算机与多媒体教学设计和教案,《电子计算机与多媒体》教学设计
  10. 常用数据结构——LinkedList