1. 程式人生 > >LeetCode#784: Letter Case Permutation

LeetCode#784: Letter Case Permutation

Description

Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create.

Example

Input: S = "a1b2"
Output: ["a1b2", "a1B2", "A1b2", "A1B2"]

Input: S = "3z4"
Output: ["3z4", "3Z4"]

Input: S = "12345"
Output: ["12345"]

Note

  • S will be a string with length between 1 and 12.
  • S will consist only of letters or digits.

Solution

我們以abc為例先把所有可能性化成一棵二叉樹:

	        (abc)
	     /          \
	 a(bc)          A(bc)
	  /  \         /     \
   ab(c) aB(c)    Ab(c)  AB(c)
   / \   /   \    /  \    / \
 abc abC aBc aBC Abc AbC ABc ABC 

可以看出,該樹的葉子節點就是abc轉換大小寫之後的所有可能性,我們的目標就是找出所有的葉子節點。

廣度優先搜尋

第一種方式是使用BFS。以輸入a1b2為例,首先把它放入一個佇列中。外迴圈第一次執行時,i指向a,佇列中也只有一個元素a1b2,這時候將a1b2出隊並且將a1b2A1b2入隊;第二次外迴圈時,i指向的1是數字,因此直接跳過;第三次外迴圈時,i指向b,因為佇列中有兩個元素因此內迴圈執行兩遍,第一遍先將a1b2出隊並將a1b2a1B2入隊,第二遍將A1b2出隊並將A1b2A1B2入隊,此時佇列中有四個元素a1b2, a1B2, A1b2, A1B2;第四次外迴圈時,i指向數字2

,因此直接跳過,迴圈結束,而此時佇列中的元素就是所有的可能性。

public class Solution {
    public List<String> letterCasePermutation(String S) {
        if(S == null) 
        	return new LinkedList<String>();
        Queue<String> queue = new LinkedList<String>();
        queue.add(S);
        
        for(int i = 0; i < S.length(); i++) {
        	if(Character.isDigit(S.charAt(i))) continue;
        	int size = queue.size();
        	for(int j = 0; j < size; j++) {
        		String curr = queue.poll();
        		char[] chars = curr.toCharArray();
        		
        		chars[i] = Character.toLowerCase(chars[i]);
        		queue.add(String.valueOf(chars));
        		
        		chars[i] = Character.toUpperCase(chars[i]);
        		queue.add(String.valueOf(chars));
        	}
        }
        return new LinkedList<String>(queue);
    }
}

深度優先搜尋

第二種方式是使用DFS。不像BFS是一層一層的遍歷,直到最後一層就是結果,DFS是直接先到達某個葉子節點,將其加入到結果列表中,然後回溯,如此反覆。

public class Solution2 {
    public List<String> letterCasePermutation(String S) {
    	if(S == null)
    		return new LinkedList<String>();
    	char[] chars = S.toCharArray();
    	List<String> res = new LinkedList<>();
    	dfs(res, chars, 0);
    	return res;
    }
    
    private void dfs(List<String> res, char[] chars, int index) {
    	if(index == chars.length) {
    		res.add(String.valueOf(chars));
    		return;
    	}
    	if(!Character.isDigit(chars[index])) {
    		chars[index] = Character.toLowerCase(chars[index]);
    		dfs(res, chars, index+1);
    		chars[index] = Character.toUpperCase(chars[index]);
    		dfs(res, chars, index+1);
    	} else {
    		dfs(res, chars, index+1);
    		return;
    	}
    }
}