秋招算法字符串专场leetcode(Easy十六题)
字符串专场
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. 赎金信
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
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
给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符:
如果一个学生的出勤记录中不超过一个’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. 反转字符串中的元音字母
输入:"hello"
输出:"holle"
输入:"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 整数类型)。
输入:
["a","a","b","b","c","c","c"]输出:
返回 6 ,输入数组的前 6 个字符应该是:["a","2","b","2","c","3"]说明:
"aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。
输入:
["a"]输出:
返回 1 ,输入数组的前 1 个字符应该是:["a"]解释:
没有任何字符串被替代。
输入:
["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. 二进制求和
输入: a = "11", b = "1"
输出: "100"
输入: 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. 有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判断字符串是否有效。
输入: "()"
输出: true
输入: "()[]{}"
输出: true
输入: "(]"
输出: false
输入: "([)]"
输出: false
输入: "{[]}"
输出: 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
,最多删除一个字符。判断是否能成为回文字符串。
输入: "aba"
输出: True
输入: "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
,返回其最后一个单词的长度。如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词。
**说明:**一个单词是指仅由字母组成、不包含任何空格字符的 最大子字符串。
输入: "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. 最长公共前缀
输入: ["flower","flow","flight"]
输出: "fl"
输入: ["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()
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
输入: haystack = "hello", needle = "ll"
输出: 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. 验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
输入: "A man, a plan, a canal: Panama"
输出: true
输入: "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十六题)相关推荐
- 2022秋招算法岗卷成人间地狱!高薪惹眼,招录比100:1
「求职卷,进来了做实验也卷,卷翻天.」 有人说,2022 年秋招算法岗人间地狱. 那么,真实情况如何? 算法岗高薪惹眼 根据Talent Seer 2020 AI人才报告显示,全球AI从业者总人数约有 ...
- 谁说2021届秋招算法岗一定要灰飞烟灭啦?
没错,这是一碗鸡汤,希望肝完这碗鸡汤的师弟师妹们就不要过度焦虑啦-理性上车,理性下车,希望萌新们都能遇到最适合自己的坑位 2014年末入坑AI,一路见证了AI行业的快速起飞.爆炸.焦虑和冷却. 小夕前 ...
- 2021届秋招算法岗真的要灰飞烟灭了吗?
星标/置顶小屋,带你解锁 最萌最前沿的NLP.搜索与推荐技术 文 | 不拖更的夕小瑶 2014年末入坑AI,一路见证了AI行业的快速起飞.爆炸.焦虑和冷却. 小夕前几天在知乎上看到一个问题<如何 ...
- 知乎热榜:如何看待 2021 年秋招算法岗灰飞烟灭?
公众号关注 "GitHubPorn" 设为 "星标",带你了解技术圈内新鲜事! 出处:https://www.zhihu.com/question/406974 ...
- 如何看待2021年秋招算法岗灰飞烟灭?
仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:知乎,https://www.zhihu.com/question/406974583 编辑:深度学习与计算机视觉 18年是否值得进入,19年供 ...
- 如何看待【2021年秋招算法岗】灰飞烟灭?
来自:知乎 链接:https://www.zhihu.com/question/406974583 XX Zhao 我以一个公司的面试官角度来回答一下这个问题吧. 我目前在tmd中一家的业务线上担任图 ...
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...
- 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 ...
- 知乎热议“如何看待 2022 年秋招算法岗人间地狱”
本文转载自IT之家 今年校招算法岗就业形势有多严峻?知乎热榜用一个词评价:"人间地狱".好家伙,去年对于该问题用的还是阳间词汇"灰飞烟灭",今年就开始唠阴间嗑了 ...
最新文章
- 推荐一个可以把网页背景色调成护眼色的Chrome扩展应用
- eclipse解决Android Library Project jar包重复导致的问题
- Spark入门阶段一之扫盲笔记
- 洛谷 1115——最大子段和(线性数据结构)
- 光源选型的要素有哪些?
- css3 下拉缩放显示定位导航
- 从零开始学编程(所以说英语也是零)
- C++实现 层次分析法(AHP)
- 安装Oracle 19c 的系统配置要求
- 差文解析 IIRC: Incremental Implicitly-Refined Classification
- Android的生命周期
- Dialog加载页面动画(Loding.....加载等待)三种方式
- 汉白玉产地在哪里_汉白玉产地在哪里?
- R_Studio(学生成绩)对数据缺失值md.pattern()、异常值分析(箱线图)
- 当下比较火的直销分销预订返佣模式系统软件定制开发
- 深信服服务器装系统,深信服新上网行为管理系统安装调试手册[1].doc.docx
- 微信最新授权登录 微信小程序无法弹出授权弹框 open-type getUserInfo获取不到用户信息 授权不弹框
- 三步实现沉浸式状态栏(即状态栏与APP同色)
- 最牛会计对账,不会这个Excel公式要崩溃
- linux下的wget命令实现断点下载
热门文章
- 伪标签Pseudo Label 与软标签 soft label
- 考研冲刺阶段的7大谣言!你中招了吗?
- 冰冰学习笔记:这些链表练习题,你会吗?(中)
- 2022年技能大赛“网络安全”(中职组)D模块电子答题卡
- iec104协议java_GitHub - renduy/IEC104_microgrid: iec104协议主站客户端程序,属于微电网管理系统一部分...
- Houdini湖边小屋-使用到的节点及VEX Fuction(更新中)
- c语言趣味算数游戏程序设计,非常经典的C语言趣味题目
- 一些简单的Linux指令
- 电子计算机与多媒体教学设计和教案,《电子计算机与多媒体》教学设计
- 常用数据结构——LinkedList