一、反转字符串中的单词III
题意:
给定一个字符串 s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
思路:
反转字符串的时候需要知道每个单词的startIndex和endIndex。通过String类的split方法将空格删去,然后计算出每一个单词的size。startIndex=endInedx+2;要把空格算上(当然起始是0);然后endIndex=startIndex+spilt[i].length()-1;
代码:
class Solution {
public String reverseWords(String s) {
char[] ch = s.toCharArray();
String[] split = s.split(" ");
int startIndex = 0;
for (int i = 0; i < split.length; i++) {
int endIndex = startIndex + split[i].length() - 1;
reverse(ch, startIndex, endIndex);
startIndex=endIndex+2;
}
return new String(ch);
}
public void reverse(char[] ch,int left,int right){
while(left<right){
char temp=ch[left];
ch[left]=ch[right];
ch[right]=temp;
left++;
right--;
}
}
}
二、反转字符串中的单词(新思路)
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
思路:
1.首先将首尾的空格删除;str.trim();然后split(" ");
2.然后使用StringBuilder从后往前拼接字符串,如果split[i]=="",直接下一个。直到遇到单词,就把它加进去,然后再append(" ");
代码:
class Solution {
public String reverseWords(String s) {
//先将整个字符串反转
String str=s.trim();
String[] strs=str.split(" ");
StringBuilder sb=new StringBuilder();
for(int i=strs.length-1;i>=0;i--){
if(strs[i].equals(""))continue;
sb.append(strs[i]+" ");
}
return sb.toString().trim();
}
}
三、字母异位词分组(使用map存储)
题意:
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
思路:
字母异位词的字母是一样的,只是顺序不一样。通过toCharArray()后,使用Arrays.sort();
就可以按照字符排序。所以使用map键值对来存。key:String(按照字符排序后的字符串),value:字母一样的集合。
每当遍历一个字符串:str.toCharArray(); 然后:Arrays.sort(ch);然后 String key=new String(ch);
然后要判断集合中是否有这个key,如果没有要先创建集合;如果有直接加入。map.get(key).add(str);
代码:
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if(strs==null||strs.length==0)return new ArrayList<>();
//使用map,key:字符串按照字符排序 value:存储拥有相同键的字符串的集合
Map<String,List<String>> map=new HashMap<>();
for(String str:strs){
//首先将str排序
char[] chs=str.toCharArray();
Arrays.sort(chs);
String key=new String(chs);
//看有没有这个
if(!map.containsKey(key)){
map.put(key,new ArrayList<>());
}
map.get(key).add(str);
}
return new ArrayList<>(map.values());
}
}
四、根据字符出现频率排序(哈希表)
思路:
1.首先一次for循环遍历记录字符出现的频率
2.其次获取map集合的键的集合keySet并且将这个集合根据value排序(重点)
3.然后遍历集合,使用StringBuilder根据value的值,拼接ch value次。
代码:
class Solution {
public String frequencySort(String s) {
//记录每一个字符出现的次数
HashMap<Character,Integer> map=new HashMap<>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
map.put(ch,map.getOrDefault(ch,0)+1);
}
//获取key的集合
List<Character> list=new ArrayList<Character>(map.keySet());
//根据key对应的value进行降序排序 nb
Collections.sort(list,(a,b)->map.get(b)-map.get(a));
//遍历拼接字符串
StringBuilder sb=new StringBuilder();
for(int i=0;i<list.size();i++){
char ch=list.get(i);
int number=map.get(ch);
for(int j=0;j<number;j++){
sb.append(ch);
}
}
return sb.toString();
}
}
五、计数二进制子串
题意:
给定一个字符串 s
,统计并返回具有相同数量 0
和 1
的非空(连续)子字符串的数量,并且这些子字符串中的所有 0
和所有 1
都是成组连续的。
重复出现(不同位置)的子串也要统计它们出现的次数。
思路:
题目中要求的是:具有相同数量0和1的非空连续子字符串的数量。eg:00011,这五个字符中0和1的个数分别是3,2。连续子字符串的数量有:01 0011两个。因此每一对相邻二进制串的拥有相同数量的0,1的xxx的数量是Math.min(0数量,1数量);
代码:
class Solution {
public int countBinarySubstrings(String s){
int size=s.length();
int[] counts=new int[size];
int index=0;
counts[0]=1;
//首先对字符串中的01计数
for(int i=0;i<size;i++){
if(i+1<size&&s.charAt(i)==s.charAt(i+1)){
counts[index]++;
}else if(i+1<size&&s.charAt(i)!=s.charAt(i+1)){
index++;
counts[index]=1;
}
}
int sum=0;
for(int i=0;i<size-1;i++){
sum+=Math.min(counts[i],counts[i+1]);
}
return sum;
}
}