题目:
你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。
个人解法:
思路:
利用深度优先遍历,建立一个hashset用来进行存储比对,建立一个flag的boolean型数组,用来存储这个字符是否被使用过。
时间:
50 ms
代码:
class Solution {
Set<String> set=new HashSet<>();
boolean[] flag;
public int numTilePossibilities(String tiles) {
if (tiles.length() == 0) {
return 0;
}
flag=new boolean[tiles.length()];
char[] ch=tiles.toCharArray();
Arrays.sort(ch);
String temp="";
helper(temp,ch);
return set.size();
}
public void helper(String temp,char[] ch){
if(temp.length()>ch.length){
return;
}
if(!set.contains(temp)&&temp.length()!=0){
set.add(temp);
// System.out.println(temp);
}
for(int i=0;i<flag.length;i++){
if(flag[i]){
continue;
}else{
flag[i]=true;
helper(temp+ch[i],ch);
flag[i]=false;
while (i < ch.length - 1 && ch[i] == ch[i + 1]) {
i++;
}
}
}
}
}
leetcode优解:
思路:
不使用hashset进行查找,而是直接计算数量,只要在排序后的数组里发现后面的字符和前面的字符相同就跳过,这样不会遇到重复。
时间:
4ms
代码:
class Solution {
int num;
public int numTilePossibilities(String tiles) {
if (tiles.length() == 0) {
return 0;
}
num = 0;
boolean[] visited = new boolean[tiles.length()];
char[] chars = tiles.toCharArray();
Arrays.sort(chars);
DFS(visited, chars, 0);
return num;
}
private void DFS(boolean[] visited, char[] chars, int len) {
if (len == chars.length) {
return;
}
for (int i = 0; i < chars.length; i++) {
if (visited[i]) {
continue;
}
num++;
visited[i] = true;
DFS(visited, chars, len + 1);
visited[i] = false;
while (i < chars.length - 1 && chars[i] == chars[i + 1]) {
i++;
}
}
}
}