第一题-字符串中的第一个唯一字符
题目
思路
1、双重遍历字符串,创建一个数组,来存储字符串中出现的字母是否重复出现,重复出现置为1,然后遍历数组,找到第一个数组元素值为0的index,返回
2、遍历一遍字符串,使用map进行存储每个字符出现的索引,发现已经存储过的,直接索引置为-1,遍历map,寻找最小的索引值
代码
1、暴力破解
public int firstUniqChar(String s) {
if(s.length() == 1) return 0;
int index = -1;
int[] arrRes = new int[s.length()];
for(int i = 0; i < s.length() - 1; i++) {
for(int j = i+1; j < s.length(); j++) {
if(s.charAt(i) == s.charAt(j)) {
arrRes[i] = 1;
arrRes[j] = 1;
break;
};
};
};
for(int i = 0; i < s.length(); i++) {
if(arrRes[i] == 0) {
index = i;
break;
};
};
return index;
}
2、map存储
public int firstUniqChar(String s) {
if(s.length() == 1) return 0;
int index = -1;
Map map = new HashMap();
for(int i = 0; i < s.length(); i++) {
char sChar = s.charAt(i);
if(map.containsKey(sChar)) {
map.replace(sChar, -1);
}else {
map.put(sChar, i);
}
};
Set<Character> keys = map.keySet();
for(char ch : keys){
if(!map.get(ch).equals(-1)) {
if(index == -1 || index > (int)map.get(ch)) {
index = (int)map.get(ch);
}
};
};
return index;
}
--------分界线-第一个是我的代码,下面的是官方代码,参考---------
public int firstUniqChar(String s) {
Map<Character, Integer> position = new HashMap<Character, Integer>();
int n = s.length();
for (int i = 0; i < n; ++i) {
char ch = s.charAt(i);
if (position.containsKey(ch)) {
position.put(ch, -1);
} else {
position.put(ch, i);
}
}
int first = n;
for (Map.Entry<Character, Integer> entry : position.entrySet()) {
int pos = entry.getValue();
if (pos != -1 && pos < first) {
first = pos;
}
}
if (first == n) {
first = -1;
}
return first;
}
第二题-赎金信
题目
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次
思路
1、使用map记录magazine中字符出现的频数,然后遍历ransomNote,一个个在map中向下减,没有在map中出现,或者小于1了,就直接返回false-(该用map不用,不该用map乱用)
2、官方思路,这种思路我还是不熟悉,直接使用编码特性,使用数组长度为26的数组进行存储每个字母出现的频率
代码
1、思路一
public boolean canConstruct(String ransomNote, String magazine) {
Map map = new HashMap();
boolean res = true;
for(int i = 0; i < magazine.length(); i++) {
if(map.containsKey(magazine.charAt(i))) {
map.replace(magazine.charAt(i), (int)map.get(magazine.charAt(i)) + 1);
}else {
map.put(magazine.charAt(i), 1);
};
};
for(int i = 0; i < ransomNote.length(); i++) {
if(map.containsKey(ransomNote.charAt(i)) && (int)map.get(ransomNote.charAt(i)) > 0) {
map.replace(ransomNote.charAt(i), (int)map.get(ransomNote.charAt(i)) - 1);
}else {
res = false;
break;
};
};
return res;
}
2、思路二
public boolean canConstruct(String ransomNote, String magazine) {
int[] arr = new int[26];
boolean res = true;
for(int i = 0; i < magazine.length(); i++) {
arr[magazine.charAt(i) - 'a']++;
};
for(int i = 0; i < ransomNote.length(); i++) {
arr[ransomNote.charAt(i) - 'a']--;
if(arr[ransomNote.charAt(i) - 'a'] < 0) {
res = false;
break;
}
};
return res;
}
第三题-有效的字母异位词
题目
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意: 若 s 和 t **中每个字符出现的次数都相同,则称 s 和 t **互为字母异位词。
思路
这不就出来了,和上一道题型官方思路一样,不多说,直接上代码
代码
public boolean isAnagram(String s, String t) {
int[] arr = new int[26];
boolean res = true;
for(int i = 0; i < s.length(); i++) {
arr[s.charAt(i) - 'a']++;
};
for(int i = 0; i < t.length(); i++) {
arr[t.charAt(i) - 'a']--;
if(arr[t.charAt(i) - 'a'] < 0) {
res = false;
break;
};
};
for(int i = 0; i < 26; i++) {
if(arr[i] != 0) {
res = false;
break;
};
};
return res;
}