1. Two Sum
找出数组中加起来等于target的两个数。每一个输入有且仅有一个解,但是同一个元素不能使用两次。
可以使用HashMap + 单遍循环,key为数组中的元素,value为下标。如果hashmap中已经存储过target - nums[i]了,那么就找到了一对结果。如果没有存储过target - nums[i],那么就将(nums[i] , i)放入HashMap。
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();//key:number Value:index
int [] ans = new int [2];
for(int i = 0; i < nums.length; i++){
if(map.containsKey(target - nums[i])){
ans[0] = map.get(target - nums[i]);
ans[1] = i;
break;
}
map.put(nums[i], i);
}
return ans;
}
}
3. Longest Substring Without Repeating Characters
给定一个字符串,找出最长的没有重复字符的子串。
滑动窗口+HashMap。HashMap的key是出现的字符,value是该字符的下标。right指针向右移动时,如果发现HashMap已经有了right指向的字符,那么说明该字符重复了,而该字符的位置正是该字符在HashMap中的value值。于是可以直接将left指针移动到该字符的下一位置。
class Solution {
public int lengthOfLongestSubstring(String s) {
char [] arr = s.toCharArray();
int left = 0;
int right = 0;
int ans = 0;
HashMap<Character,Integer> map = new HashMap<>();
for(; right < arr.length; right++){
if(map.containsKey(arr[right])){
left = Math.max(left, map.get(arr[right])+1);
}
ans = Math.max(ans, right - left +1);
map.put(arr[right], right);
}
return ans;
}
}
30. Substring with Concatenation of All Words
给定一个字符串s,和一个单词列表words,words中的每个词长度相等。需要在s中寻找,包含全部词,且每个词只出现一次,没有任何多余其他字符的子串。
本题使用HashMap来存储words中的词。key是词,value是该词在words中出现次数。
words中每个词的长度都是一样的,我们可以假设每个词的长度为length,而一共有n个词,所以满足要求的子串必然是长度为 n * length 的子串
于是我们遍历每一个长度为 n * length的子串,子串也有自己的HashMap,如果子串的某一个词在words的HashMap中没有,或者这个词在子串中出现的次数大于words的HashMap,那么这个子串就不符合要求。当遍历完整个字串之后,如果这个子串没有break掉,那就是一个正确的解。
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> ans = new ArrayList<>();
if(s == null || s.length() == 0 || words == null || words.length==0){
return ans;
}
int numOfWords = words.length;
int lenOneWord = words[0].length();
int len = numOfWords * lenOneWord;
HashMap<String, Integer> map = new HashMap<>();
for(String str: words){
map.put(str, map.getOrDefault(str,0)+1);
}
for(int i = 0 ; i <= s.length() - len;i++){
HashMap<String, Integer> strCount = new HashMap<>();
int j = 0;
for(; j < numOfWords; j++){
String subs = s.substring(i+j*lenOneWord, i+(j+1)*lenOneWord);
if(!map.containsKey(subs)){
break;
}
strCount.put(subs , strCount.getOrDefault(subs, 0)+1 );
if(strCount.get(subs) > map.get(subs)){
break;
}
}
if(j == numOfWords){
ans.add(i);
}
}
return ans;
}
}
36. Valid Sudoku
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
1 . 数字 1-9 在每一行只能出现一次。
2 . 数字 1-9 在每一列只能出现一次。
3 . 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
做法很简单,为每一行每一列每一个3x3宫都建一个HashMap,这题可真HashMap。
HashMap也可以用一个长度为9的数组替代。
class Solution {
public boolean isValidSudoku(char[][] board) {
HashMap<Character, Integer> rows[] = new HashMap [9];
HashMap<Character, Integer> columns[] = new HashMap[9];
HashMap<Character, Integer> box[] = new HashMap[9];
for(int i = 0; i <9; i++){
rows[i] = new HashMap<Character, Integer>();
columns[i] = new HashMap<Character, Integer>();
box[i] = new HashMap<Character, Integer>();
}
for(int i = 0; i < 9; i++){
for(int j = 0; j <9; j++){
if(board[i][j] == '.'){
continue;
}
rows[i].put(board[i][j] , rows[i].getOrDefault(board[i][j], 0) + 1);
columns[j].put(board[i][j] , columns[j].getOrDefault(board[i][j], 0) + 1);
int numOfBox = (i/3) * 3 + (j/3);
box[numOfBox].put(board[i][j] , box[numOfBox].getOrDefault(board[i][j], 0) + 1);
if(rows[i].get(board[i][j]) >1 ||
columns[j].get(board[i][j]