[关闭]
@ysongzybl 2015-05-25T01:36:07.000000Z 字数 4617 阅读 1041

Summary : Problems solved with DFS recursions I

interview


1. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return [["aa","b"],["a","a","b"]]

Idea:
Given a string with length n, for a number i<n, if s.substring(0,i) is a palindrome, then keep on searching s.substring(i,n)

  1. public boolean isPalindrome(String s){
  2. int front = 0, back = s.length()-1;
  3. while(front<back){
  4. if(s.charAt(front) != s.charAt(back)) return false;
  5. front++;
  6. back--;
  7. }
  8. return true;
  9. }
  10. public void dfs(List<List<String>> res, String s, ArrayList<String> sol, int cur_idx){
  11. if(cur_idx == s.length()){
  12. List<String> path = new ArrayList<String>(sol);
  13. res.add(path);
  14. return;
  15. }
  16. for(int len=1; len<=s.length()-cur_idx; len++){
  17. String candidate = s.substring(cur_idx, cur_idx+len);
  18. if(isPalindrome(candidate)){
  19. sol.add(candidate);
  20. dfs(res, s, sol, cur_idx+len);
  21. sol.remove(sol.size()-1);
  22. }
  23. }
  24. }
  25. public List<List<String>> partition(String s) {
  26. List<List<String>> res = new ArrayList<List<String>>();
  27. int n = s.length();
  28. if(n==0) return res;
  29. ArrayList<String> sol = new ArrayList<String>();
  30. dfs(res, s, sol, 0);
  31. return res;
  32. }

2. Restore IP addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

For example:
Given "25525511135",
return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)

Idea:
Similar to the Palindrome Partitioning problem:
Given a string with length n, for a number i<n, if s.substring(0,i) is a valid number segment, then keep on searching s.substring(i,n)

Each number in a valid IP address is in range [0,255].
Note:
1. For the string number representation, make sure check its format: 00111 is not valid
2. Terminate conditions :

- Each valid IP contains only 4 segments
- Terminate if current idx in given string exceeds the range bound
  1. public class Solution {
  2. public boolean valid(String num){
  3. if(num.length()>1 && num.charAt(0)=='0') return false; // mistake : 010 is not a valid num
  4. if(num.length()<=3 && Integer.valueOf(num) < 256) return true;
  5. return false;
  6. }
  7. public void dfs(List<String> res, String s, StringBuilder ip, int cur_idx, int seg_count){
  8. int n = s.length();
  9. if(cur_idx==n && seg_count == 4){
  10. res.add(ip.toString());
  11. return;
  12. }
  13. for (int len=1; len <= 3; len++){
  14. if(cur_idx+len>n) break; // mistake: must check range bound
  15. String num = s.substring(cur_idx, cur_idx+len);
  16. if(valid(num)){
  17. int pos_backup = ip.length();
  18. if(ip.length()==0) ip.append(num);
  19. else ip.append("."+num);
  20. dfs(res, s, ip, cur_idx+len, seg_count+1);
  21. ip.delete(pos_backup, ip.length()); // mistake: not staring from cur_idx, since extra dots were added
  22. }
  23. }
  24. }
  25. public List<String> restoreIpAddresses(String s) {
  26. List<String> res = new ArrayList<String>();
  27. int n = s.length();
  28. if(n==0||n>12) return res;
  29. StringBuilder ip = new StringBuilder();
  30. dfs(res, s, ip, 0, 0);
  31. return res;
  32. }
  33. }

3. Letter Combinations of a Phone Number

Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.

Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

  1. public void dfs(List<String> res, String digits, StringBuilder sol, int cur_idx, HashMap<Character, String> letters){
  2. if(cur_idx == digits.length()) {
  3. res.add(sol.toString());
  4. return;
  5. }
  6. String candidates = letters.get(digits.charAt(cur_idx));
  7. for(int i=0; i<candidates.length(); i++){
  8. sol.append(candidates.charAt(i));
  9. dfs(res, digits, sol, cur_idx+1, letters);
  10. sol.deleteCharAt(sol.length()-1);
  11. }
  12. }
  13. public List<String> letterCombinations(String digits) {
  14. List<String> res = new ArrayList<String>();
  15. if(digits.length()==0) return res;
  16. HashMap<Character, String> letters = new HashMap<Character, String>();
  17. String combs[] = {"","", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
  18. for(int i='0'; i<='9'; i++){
  19. letters.put((char)i, combs[i-'0']); // put(i, ...) will treat i as an integer
  20. }
  21. StringBuilder sol = new StringBuilder();
  22. dfs(res, digits, sol, 0, letters);
  23. return res;
  24. }

4. Print Numbers By Recursion

Print numbers from 1 to the largest number with N digits by recursion.

Example
Given N = 1, return [1,2,3,4,5,6,7,8,9].
Given N = 2, return [1,2,3,4,5,6,7,8,9,10,11,12,...,99].

Do it in recursion, with at most N depth.

Idea:
Simulate number using char array : ['0','1','0'] => 10
0-9 Permutations

  1. public void dfs(List<Integer> res, char[] num, int cur_idx, int n){
  2. if(cur_idx==n-1){
  3. // convert char array to integer
  4. int x = 0;
  5. for(char c : num){
  6. x = x * 10 + (int) c - (int) '0';
  7. }
  8. res.add(x);
  9. return;
  10. }
  11. for(char c='0'; c<='9'; c++){
  12. num[cur_idx+1] = c;
  13. dfs(res, num, cur_idx+1, n);
  14. }
  15. }
  16. public List<Integer> numbersByRecursion(int n) {
  17. List<Integer> res = new ArrayList<Integer>();
  18. if(n==0) return res;
  19. char num[] = new char[n];
  20. for(char i='0'; i<='9'; i++){
  21. num[0]=i;
  22. dfs(res, num, 0, n);
  23. }
  24. res.remove(0); // 0 does not count, always starts from 1
  25. return res;
  26. }

5. Sudoku Solver (TODO)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注