目录
1.转换成小写字母
2.字符串中的单词数
3.交替合并字符串
转为数组
转为StringBuilder
4.字符串压缩
5.关于同构
有效的字母异位词
字符串的排列
6.长度最小的子数组
7.小结
1.转换成小写字母
709. 转换成小写字母
难度简单220
给你一个字符串
s
,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串
// class Solution {
// public String toLowerCase(String s) {
// return s.toLowerCase();
// }
// }
class Solution {public String toLowerCase(String s) {StringBuilder sb = new StringBuilder();for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if (ch >= 'A' && ch <= 'Z') {sb.append((char)(ch+32));}else{sb.append(ch);}}return sb.toString();}
}
2.字符串中的单词数
434. 字符串中的单词数
难度简单194
统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。
请注意,你可以假定字符串里不包括任何不可打印的字符。
示例:
输入: "Hello, my name is John" 输出: 5 解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。
class Solution {public int countSegments(String s) {String[] str=s.split(" ");int count=0;//可以避免我们去判断字符串为空或者字符串长度为零然后return 0 的情况for(int i=0;i<str.length;i++){if(str[i].length()!=0){//字符串长度不为0//这里有个很奇怪的测试用例",,,, hello"count++;}}return count;}
}
3.交替合并字符串
1768. 交替合并字符串
难度简单74
给你两个字符串
word1
和word2
。请你从word1
开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。返回 合并后的字符串 。
转为数组
class Solution {public static String mergeAlternately(String word1, String word2) {char[] arr1=word1.toCharArray();char[] arr2=word2.toCharArray();int len1=arr1.length,len2=arr2.length,i=0,j=0;char[] arr=new char[len1+len2]; while(i<len1||i<len2){if(i<len1){arr[j++]=arr1[i];}if(i<len2){arr[j++]=arr2[i];}i++;}String word=new String(arr);return word;}}
转为StringBuilder
class Solution {public String mergeAlternately(String word1, String word2) {int m = word1.length(), n = word2.length();int i = 0, j = 0;StringBuilder ans = new StringBuilder();while (i < m || j < n) {if (i < m) {ans.append(word1.charAt(i));++i;}if (j < n) {ans.append(word2.charAt(j));++j;}}return ans.toString();}
}
4.字符串压缩
面试题 01.06. 字符串压缩
难度简单156
字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串
aabcccccaaa
会变为a2b1c5a3
。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)
暴力求解
- 当然你也可以把i=0时的情况对lastChar,lastCharNum初始化,然后循环从i=1开始,都行。
- i++后,如果 现在的元素cur和上一个元素lastChar相同,就让num++;
- 否则就把上个字符,上个字符个数追加到我们设定的stringBuilder上,cur赋值给lastChar,更新lastCharNum=1。
- 需要上步每次追加的都是上个字符,对最后出现的字符需要特殊处理,再次进行追加。
public String Main(String str) {StringBuilder stringBuilder = new StringBuilder();char lastChar = 0;int lastCharNum = 0;for (int i = 0; i < str.length(); i++) {if (i == 0) {lastChar = str.charAt(0);lastCharNum = 1;continue;}char cur = str.charAt(i);if (lastChar == cur) {lastCharNum++;} else {stringBuilder.append(lastChar).append(lastCharNum);//上次的lastChar = cur;lastCharNum = 1;}if (i == str.length() - 1) {stringBuilder.append(lastChar).append(lastCharNum);//最后一次的单独弄}}return stringBuilder.length() > str.length() ? str : stringBuilder.toString();}
实际上这个方法效率还是比较低的。
5.关于同构
有效的字母异位词
242. 有效的字母异位词
难度简单708
给定两个字符串
s
和t
,编写一个函数来判断t
是否是s
的字母异位词。注意:若
s
和t
中每个字符出现的次数都相同,则称s
和t
互为字母异位词。示例 1:
输入: s = "anagram", t = "nagaram" 输出: true判断是否为同构吧
- 字符减去字符等于数字
- Arrays.equals(arr1,arr2)方法中,当arr1完全等同arr2,返回true 。完全相同就是数组中每一位的元素和元素的个数,数组长度都相同。
class Solution {public boolean isAnagram(String s, String t) {int len1=s.length();int len2=t.length();if(len1!=len2) return false;int[] arr1=new int[26],arr2=new int[26];for(int i=0;i<len1;i++){arr1[s.charAt(i)-'a']++;arr2[t.charAt(i)-'a']++;}return Arrays.equals(arr1,arr2);//如果两个数组以相同的顺序包含相同的元素,//则它们是相等的。此外,如果两个数组引用都为空,则认为它们相等。}
}
字符串的排列
567. 字符串的排列
难度中等
给你两个字符串
s1
和s2
,写一个函数来判断s2
是否包含s1
的排列。如果是,返回true
;否则,返回false
。换句话说,
s1
的排列之一是s2
的 子串 。示例 1:
输入:s1 = "ab" s2 = "eidbaooo" 输出:true 解释:s2 包含 s1 的排列之一 ("ba").示例 2:
输入:s1= "ab" s2 = "eidboaoo" 输出:false
- 设定left和right指针(left=0,right=len1-1)指向s2, arr1数组存储s1中元素和每个元素的个数,arr2存储s2的,并且先让arr1和arr2都存储len1个长度 的元素和(因为你要找的同构元素就是 len1 长度)
- 如果s2的前len1个字符就是s1的同构字符串,直接return true;
- 否则就让right++,存储right这个位置的元素和到目前为止这个元素个数++,arr2[s2.charAt(right)-'a']++; 紧接着arr2[s2.charAt(left)-'a']--,left++。
- 在上述陈述中,由于是进入循环right<len2后,,s2字符串的最后一位下标是len2-1,如果当上次right已经走到len2-1的位置,都没找到,然后进入循环,right++,此时right=len2了,超过了s2最大下标了都,所以加上判断条件if(right!=len2),这步也可以先不写让他报错后你根据他给的提示的测试用例发现这个越界问题。
class Solution {public boolean checkInclusion(String s1, String s2) {int len1=s1.length(), len2=s2.length();if(len1>len2) return false;int[] arr1=new int[26],arr2=new int[26];for(int i=0;i<len1;i++){arr1[s1.charAt(i)-'a']++;arr2[s2.charAt(i)-'a']++;}int left=0,right=len1-1;while(right<len2){if(Arrays.equals(arr1,arr2)) return true;right++;if(right!=len2){arr2[s2.charAt(right)-'a']++;}arr2[s2.charAt(left)-'a']--;left++;}return false;}
}
6.长度最小的子数组
209. 长度最小的子数组
难度中等1510
给定一个含有
n
个正整数的数组和一个正整数target
。找出该数组中满足其和
≥ target
的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回0
。示例 1:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组[4,3]
是该条件下的长度最小的子数组。
思路
利用滑动窗口,设定start和end指针 (最初都指向数组的第一个元素),设定合适的窗口,进行移动,ret(子数组的长度的最小值)来接受最终返回的值每次更新迭代,sum记录从start到end之间元素的和(并且让sum初始化为0),target为目标值。
- 注意看题:是 连续子数组 !
- 让flag默认值是1,先让end移动,让sum先等于nums[end];
- 如果sum<target,end右移,flag = 1,更新sum,sum+=nums[end];
- 如果sum>=target,start右移,flag = -1,更新sum,sum-=nums[start-1];
- 循环,只要end<nums.length就行
class Solution {public int minSubArrayLen(int target, int[] nums) {int ret=Integer.MAX_VALUE;//返回值默认为最大值;int sum=0;int start=0;int end=0;int flag=1;while(end<nums.length){if(flag==1){sum+=nums[end];}else{sum-=nums[start-1];}if(sum>=target){ret=Math.min(ret,end-start+1);start++;flag=-1;}else{end++;flag=1;}}return ret==Integer.MAX_VALUE?0:ret;}
}
然后在评论区学习了一种简洁的代码
class Solution {public int minSubArrayLen(int s, int[] nums) {int i = 0;int sum = 0;int len = 0;for (int j = 0; j < nums.length; j++) {sum += nums[j];while (sum >= s) {len = len == 0 ? j - i + 1 : Math.min(len, j - i + 1);sum -= nums[i++];}}return len;} }
7.小结
写到这是方便我复习的哈哈哈哈哈哈,晚安!