leetcode最优解整理(dfs/String/Binary Search/Two pointers/Math/Dynamic programming)

本文整理了LeetCode中涉及深度优先搜索(DFS)、字符串操作及二分查找法的题目,包括Two Sum、Letter Combinations、Median of Two Sorted Arrays等经典问题的解法和思路。
摘要由CSDN通过智能技术生成

从今天开始将自己做过的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
求n对()产生的parentheses
思路:dfs,保证每一对的left必在right前
	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,求所有可能
思路:backtracking。用一维数组代表每行填的列标号。依次遍历每一行,找到所有可能(Start row by row, and loop through columns
	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
最长回文字串。
思路:中心扩展。注意以i为中心和i i + 1为中心两情况
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);
	}
6. ZigZag Conversion
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值