从今天开始将自己做过的leetcode进行整理,争取做到bug-free~
recursive and dfs
1. Two Sum
根据target求两数在数组中的index
思路:用HashMap(时间复杂度o(n))
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
if (numbers == null || numbers.length < 2) {
return res;
}
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < numbers.length; i++) {
if (map.containsKey(target - numbers[i])) {
res[0] = i;
res[1] = map.get(target - numbers[i]);
return res;
} else {
map.put(numbers[i], i);
}
}
return res;
}
方法2:敏感关键字array和target,想到二分查找法(但需要一点一点挪low和high指针)。
排序后,target == numbers[low]+numbers[high],记录copy[low]和copy[high];target >numbers[low]+numbers[high],说明最大的和最小的加一起还小于target,所以小值要取大一点,即low++;target
17. Letter Combinations of a Phone Number
给定string(数字组成),输出在键盘上对应的字母组合。
思路:Backtracking
public List<String> letterCombinations(String digits) {
LinkedList<String> ans = new LinkedList<String>();
String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
ans.add("");
for(int i =0; i<digits.length();i++){
int x = Character.getNumericValue(digits.charAt(i));
while(ans.peek().length() == i) { // res中每个string的长度和已遍历的数字个数相同
String t = ans.remove();
for(char s : mapping[x].toCharArray())
ans.add(t+s);
}
}
return ans;
}
public List<String> letterCombinations(String digits) {
List<String> res = new ArrayList<String>();
if (digits.isEmpty()) { // 必不可少
return res;
}
res.add("");
String[] s = {" ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
char[] array = digits.toCharArray();
for (int i = 0; i <= digits.length() - 1; i++) {
int d = array[i] - '0';
List<String> list = new ArrayList<String>();
if (d != 1) {
for (int j = 0; j < res.size(); j++) {
list.add(res.get(j) + s[d].charAt(0));
list.add(res.get(j) + s[d].charAt(1));
list.add(res.get(j) + s[d].charAt(2));
if (d == 7 || d == 9) {
list.add(res.get(j) + s[d].charAt(3));
}
}
}
res = list;
}
return res;
}
22. Generate Parentheses
public List<String> generateParenthesis(int n) {
ArrayList<String> res = new ArrayList<String>();
if (n <= 0) {
return res;
}
dfs(res, "", n, n);
return res;
}
public void dfs(ArrayList<String> res,String tmp,int left,int right) {
if(left == 0 && right == 0) {
res.add(tmp);
return;
}
if(left > 0) {
dfs(res, tmp + "(", left - 1, right);
}
if(left<right) {
dfs(res, tmp + ")", left, right - 1);
}
}
51. N-Queens
the n-queens puzzle:可以横竖直走,斜对角方向直走(从[0,0]到[n,n]),n行n列填n个Q,求所有可能)
public List<List<String>> solveNQueens(int n) {
List<List<String>> re = new ArrayList<List<String>>();
if(n == 1) {
List<String> l = new ArrayList<String>();
l.add("Q");
re.add(l);
return re;
}
int[] Q = new int[n];
DFS(n, Q, re, 0);
return re;
}
public static void DFS(int n, int[] Q, List<List<String>> re, int row) {
if(row == n) {
List<String> list = new ArrayList<String>();
// put
for(int i = 0; i < n; i++) {
String s = "";
for(int j = 0; j < n; j++) {
if(Q[i] == j) s += "Q";
else s += ".";
}
list.add(s);
}
re.add(list);
} else {
for(int j = 0; j < n; j++) { // 每一列
Q[row] = j;
if(isValid(row, Q))
DFS(n, Q, re, row + 1);
}
}
}
public static boolean isValid(int row, int[] Q) {
for(int i = 0; i < row; i++) {
if(Q[row] == Q[i] || Math.abs(Q[row] - Q[i]) == (row - i))
return false;
}
return true;
}
52. N-Queens II
return the total number of distinct solutions.
和上题一样
public static int count = 0;
public int totalNQueens(int n) {
if(n == 1) return 1;
int[] Q = new int[n];
int re =DFS(n, Q, 0, 0);
return re;
}
public static int DFS(int n, int[] Q, int row, int count) {
if(row == n)
count++;
else {
for(int j = 0; j < n; j++) { // 每一列
Q[row] = j;
if(isValid(row, Q))
count = DFS(n, Q, row + 1, count);
}
}
return count;
}
public static boolean isValid(int row, int[] Q) {
for(int i = 0; i < row; i++) {
if(Q[row] == Q[i] || Math.abs(Q[row] - Q[i]) == (row - i))
return false;
}
return true;
}
200. Number of Islands
Given a 2d grid map of '1'
s (land) and '0'
s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
11110
11010
11000
00000
Answer: 1
Example 2:
11000
11000
00100
00011
Answer: 3
private int n;
private int m;
public int numIslands(char[][] grid) {
int count = 0;
n = grid.length;
if (n == 0) return 0;
m = grid[0].length;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++)
if (grid[i][j] == '1') {
DFSMarking(grid, i, j);
++count;
}
}
return count;
}
private void DFSMarking(char[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != '1') return;
grid[i][j] = '0';
DFSMarking(grid, i + 1, j);
DFSMarking(grid, i - 1, j);
DFSMarking(grid, i, j + 1);
DFSMarking(grid, i, j - 1);
}
String
3. Longest Substring without repeating characters
思路:1 中心扩展,以每个char为中心找到最大的不重复子集(时间:n*n,不好)
2 map存储遍历的值出现的最后一次位置。若遍历的当前值在map中存在,替换为map中此值位置+1和start的最大值(示例:abba)时间复杂度:o(n)
public int lengthOfLongestSubstring2(String s) {
if (s.length() == 0) return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0, start = 0;
for (int i = 0; i < s.length(); ++i) {
if (map.containsKey(s.charAt(i))) {
start = Math.max(start, map.get(s.charAt(i)) + 1);
}
map.put(s.charAt(i), i);
max = Math.max(max, i - start + 1);
}
return max;
}
3 set。两个指针,fast指向j,若not in set中,add;否则用slow除掉start至j的所有值,直到j可以放进来
bug: string为空,s.length()引起NullPointerException
public int lengthOfLongestSubstring(String s) {
int i = 0, j = 0, max = 0;
Set<Character> set = new HashSet<>();
while (j < s.length()) {
if (!set.contains(s.charAt(j))) {
set.add(s.charAt(j++));
max = Math.max(max, set.size());
} else {
set.remove(s.charAt(i++));
}
}
return max;
}
5. Longest Palindromic Substring
public String longestPalindrome(String s) {
if(s.isEmpty()) return "";
if(s.length() == 1) return s;
String longest = "";
for(int i = 0; i < s.length() - 1; i++) {
String s1 = helper(s, i, i);
if(s1.length() > longest.length())
longest = s1;
s1 = helper(s, i, i + 1);
if(s1.length() > longest.length())
longest = s1;
}
return longest;
}
public static String helper(String s, int l, int r) {
while(l >= 0 && r <= s.length() - 1 && s.charAt(l) == s.charAt(r)) {
l--;
r++;
}
return s.substring(l + 1,r);
}