A
/ \
B C
/ \ / \
D E F G
/ \
H I
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
// visit top.
if (top.left != null) {
queue.offer(top.left);
}
if (top.right != null) {
queue.offer(top.right);
}
}
Given a binary tree, return its level order traversal.
A
/ \
B C
/ \ / \
D E F G
/ \
H I
Given a binary tree, return its level order traversal.
The output is A B C D E F G H I
What if we want to separate each level?
Given a binary tree, return its level order traversal.
3
/ \
9 20
/ \
15 7
[ [3], [9,20], [15,7] ]
Given a binary tree, return its level order traversal.
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.offer(root);
}
while (!queue.isEmpty()) {
List<Integer> oneResult = new ArrayList<>();
Queue<TreeNode> queue2 = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top.left != null) {
queue2.offer(top.left);
}
if (top.right != null) {
queue2.offer(top.right);
}
oneResult.add(top.val);
}
results.add(oneResult);
queue = queue2;
}
return results;
}比较优化的做法是记录每层的size
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
queue.offer(null);//分隔符
List<Integer> oneResult = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top == null) { //分隔符,标志着一层的结束
results.add(oneResult);
if (!queue.isEmpty()) {
queue.offer(null);//分隔符
}
oneResult = new ArrayList<>();
} else {
if (top.left != null) {
queue.offer(top.left);
}
if (top.right != null) {
queue.offer(top.right);
}
oneResult.add(top.val);
}
}
return results;
}Given a binary tree, return its zigzag level order traversal.
3
/ \
9 20
/ \
15 7
[
[3],
[20,9],
[15,7]
]
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.offer(root);
}
boolean isOdd = true;
while (!queue.isEmpty()) {
List<Integer> oneResult = new ArrayList<>();
Queue<TreeNode> queue2 = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top.left != null) {
queue2.offer(top.left);
}
if (top.right != null) {
queue2.offer(top.right);
}
oneResult.add(top.val);
}
if (!isOdd) {
Collections.reverse(oneResult);
}
results.add(oneResult);
isOdd = !isOdd;
queue = queue2;
}
return results;
}也可以根据isOdd,
决定左右添加的顺序,这样可能用到两头的deque会更方便些.
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
if (root == null)
return results;
Stack<TreeNode> stack = new Stack<>(); //也可以考虑使用deque
stack.push(root);
boolean isOdd = true;
while (!stack.isEmpty()) {
List<Integer> oneResult = new ArrayList<>();
Stack<TreeNode> stack2 = new Stack<>();
while (!stack.isEmpty()) {
TreeNode top = stack.pop();
if (!isOdd) {
if (top.right != null)
stack2.push(top.right);
if (top.left != null)
stack2.push(top.left);
} else {
if (top.left != null)
stack2.push(top.left);
if (top.right != null)
stack2.push(top.right);
}
oneResult.add(top.val);
}
results.add(oneResult);
stack = stack2;
isOdd = !isOdd;
}
return results;
}BFS
Given a binary tree, find the leftmost value in the last row of the tree.
1 / \ 2 0 \ / \ 4 7 9
Result: 4
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int leftValue = 0;
boolean isFirst = false;
while (!queue.isEmpty()) {
isFirst = true;
Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (isFirst) {
leftValue = top.val;
isFirst = false;
}
if (top.left == null && top.right == null) {
continue;
}
if (top.left != null) {
queue2.offer(top.left);
}
if (top.right != null) {
queue2.offer(top.right);
}
}
queue = queue2;
}
return leftValue;
}Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
1 / \ 2 2 / \ / \ 3 4 4 3
1 / \ 2 2 / \ 3 4
1 / \ 2 2 / \ 3 3
3
2
3
DFS
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
BFS
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
queue.offer(null);
int minDepth = 1;
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top == null) {
minDepth++;
queue.offer(null);
continue;
}
if (top.left == null && top.right == null) {
return minDepth;
}
if (top.left != null) {
queue.offer(top.left);
}
if (top.right != null) {
queue.offer(top.right);
}
}
return minDepth;
}public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int minDepth = 1;
while (!queue.isEmpty()) {
Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top.left == null && top.right == null) {
return minDepth;
}
if (top.left != null) {
queue2.offer(top.left);
}
if (top.right != null) {
queue2.offer(top.right);
}
}
minDepth++;
queue = queue2;
}
return minDepth;
}There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction.
Given the ball's start position, the destination and the maze, find the shortest distance for the ball to stop at the destination. The distance is defined by the number of empty spaces traveled by the ball from the start position (excluded) to the destination (included). If the ball cannot stop at the destination, return -1.
The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The start and destination coordinates are represented by row and column indexes.
Example 1
Input 1: a maze represented by a 2D array
0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 1
0 0 0 0 0
Input 2: start coordinate (rowStart, colStart) = (0, 4)
Input 3: destination coordinate (rowDest, colDest) = (4, 4)
Output: 12
Explanation: One shortest way is :
left -> down -> left -> down -> right -> down -> right. The total distance is
1 + 1 + 3 + 1 + 2 + 2 + 2 = 12.
We need to use BFS to solve the problem since it wants to get the shortest way. And BFS could simulate the behavior well.
The most important thing is to let the queue mock the action that the ball will continue rolling till it hits the edge or a block.
As long as we can mock this operation, it will be much easier for us to solve the problem.
How do we simulate this operation?
For each step we pop from queue, we need to use a while loop to keep rolling the ball till the end
class Pair {
int x;
int y;
public Pair(int a, int b) {
x = a;
y = b;
}
}
public int findShortestWay(int[][] maze, int[] start, int[] dest) {
int row = maze.length;
int col = maze[0].length;
int[][] distance = new int[row][col];
for (int i = 0; i < row; i ++) {
for (int j = 0; j < col; j ++) {
distance[i][j] = Integer.MAX_VALUE;
}
}
int[] dx = new int[] {1, 0, 0, -1};
int[] dy = new int[] {0, -1, 1, 0};
Queue<Pair> queue = new LinkedList<Pair>();
queue.offer(new Pair(start[0],start[1]));
distance[start[0]][start[1]] = 0;
while (!queue.isEmpty()) {
Pair current = queue.poll();
for (int i = 0; i < 4; i ++) {
int x = current.x;
int y = current.y;
int dist = distance[x][y];
while (x >= 0 && x < row && y >= 0 & y < col && maze[x][y] == 0) {
x += dx[i];
y += dy[i];
dist ++;
}
x -= dx[i];
y -= dy[i];
--dist;
if (distance[x][y] > dist) {
distance[x][y] = dist;
if (x != dest[0] || y != dest[1]) {
queue.offer(new Pair(x, y));
}
}
}
}
int res = distance[dest[0]][dest[1]];
return res == Integer.MAX_VALUE ? -1 : res;
}There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up (u), down (d), left (l) or right (r), but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. There is also a hole in this maze. The ball will drop into the hole if it rolls on to the hole.
Given the ball position, the hole position and the maze, your job is to find out how the ball could drop into the hole by moving shortest distance in the maze. The distance is defined by the number of empty spaces the ball go through from the start position (exclude) to the hole (include). Output the moving directions by using 'u', 'd', 'l' and 'r'. Since there may have several different shortest ways, you should output the lexicographically smallest way. If the ball cannot reach the hole, output "impossible".
The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The ball and hole coordinates are represented by row and column indexes.
Example:
Input 1: a maze represented by a 2D array
0 0 0 0 0
1 1 0 0 1
0 0 0 0 0
0 1 0 0 1
0 1 0 0 0
Input 2: ball coordinate (rowBall, colBall) = (4, 3)
Input 3: hole coordinate (rowHole, colHole) = (0, 1)
Output: "lul"
Explanation: There are two shortest ways for the ball to drop into the hole.
The first way is left -> up -> left, represented by "lul".
The second way is up -> left, represented by 'ul'.
Both ways have shortest distance 6, but the first way is lexicographically smaller because 'l' < 'u'. So the output is "lul".
We still need to use BFS to solve the problem.
We need to use a Path to keep the result since even within the same shortest way, we want to output the smallest one in lexicographical order.
The other part is very similar to The Maze II. But one thing to keep in mind:
If you hit the destination, since it is a trap, you can stop immediately instead of keeping rolling foward.
public String findShortestWay(int[][] maze, int[] ball, int[] hole) {
int row = maze.length;
int col = maze[0].length;
int[] dx = new int[] {1, 0, 0, -1};
int[] dy = new int[] {0, -1, 1, 0};
String[] dir = new String[] {"d", "l", "r", "u"};
int[][] distance = new int[row][col];
for (int i = 0; i < row; i ++) {
for (int j = 0; j < col; j ++) {
distance[i][j] = Integer.MAX_VALUE;
}
}
distance[ball[0]][ball[1]] = 0;
Queue<Pair> queue = new LinkedList<Pair>();
queue.offer(new Pair(ball[0], ball[1]));
String[][] path = new String[row][col];
path[ball[0]][ball[1]] = "";
while(!queue.isEmpty()) {
Pair cur = queue.poll();
for(int i = 0; i < 4; i++) {
int x = cur.x, y = cur.y;
int dist = distance[x][y];
String currentPath = path[x][y];
while(x >= 0 && x < row && y >= 0 && y < col && maze[x][y] == 0
&& (x != hole[0] || y != hole[1])) {
x += dx[i];
y += dy[i];
dist ++;
}
if (x != hole[0] || y != hole[1]) {
x -= dx[i];
y -= dy[i];
dist --;
}
String newPath = currentPath.concat(dir[i]);
if (distance[x][y] > dist || (distance[x][y] == dist
&& path[x][y].compareTo(newPath) > 0)) {
distance[x][y] = dist;
path[x][y] = newPath;
if (x != hole[0] || y != hole[1]) queue.offer(new Pair(x, y));
}
}
}
String result = path[hole[0]][hole[1]];
return distance[hole[0]][hole[1]] == Integer.MAX_VALUE ? "impossible" : result;
}Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
For example,
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Note:
DFS
BFS
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
cog
transformed_words <- beginWord
while (transformed_words is not empty) {
for (word_b in transformed_words) {
if (endWord is within 1 distance) {
return distance
}
if (some word in dict is within 1 distance
&& it is not in transformed_words) {
transformed_words.add(word)
}
}
update distance
}
return 0
How to check?
transformed_words <- beginWord
while (transformed_words is not empty) {
for (word_b in transformed_words) {
if (endWord is within 1 distance) {
return distance
}
if (some word in dict is within 1 distance
&& it is not in transformed_words) {
transformed_words.add(word)
}
}
update distance
}
return 0
How to check?
transformed_words <- beginWord
while (transformed_words is not empty) {
for (word_b in transformed_words) {
if (endWord is within 1 distance) {
return distance
}
if (some word in dict is within 1 distance
&& it is not in transformed_words) {
transformed_words.add(word)
}
}
update distance
}
return 0
How to check?
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> wordSet = new HashSet<>();
for(String aWord: wordList) {
wordSet.add(aWord);
}
Queue<String> queue = new LinkedList<>();
queue.offer(beginWord);
Set<String> visited = new HashSet<>();
visited.add(beginWord);
int distance = 1;
while (!queue.isEmpty()) {
Queue<String> queue2 = new LinkedList<>();
distance++;
while (!queue.isEmpty()) {
String top = queue.poll();
List<String> wordsWithinDistance =
getWordsWithinDistance(wordSet, top);
for (String word : wordsWithinDistance) {
if (word.equals(endWord)) {
return distance;
}
if (!visited.contains(word)) {
queue2.add(word);
visited.add(word);
}
}
}
queue = queue2;
}
return distance;
}public ArrayList<String> getWordsWithinDistance(Set<String> wordSet, String word) {
ArrayList<String> results = new ArrayList<>();
char[] wordCharArr = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
char oriChar = wordCharArr[i];
for (char c = 'a'; c <= 'z'; c++) {
if (c == oriChar) {
continue;
}
wordCharArr[i] = c;
String newStr = new String(wordCharArr);
if (wordSet.contains(newStr)) {
results.add(newStr);
}
}
wordCharArr[i] = oriChar;
}
return results;
} public int ladderLength(String beginWord, String endWord,
List<String> wordList) {
Set<String> wordSet = new HashSet<>();
for(String aWord: wordList) {
wordSet.add(aWord);
}
Queue<String> queue = new LinkedList<>();
queue.offer(beginWord);
int distance = 1;
while (!queue.isEmpty() && !wordSet.isEmpty()) {
Queue<String> queue2 = new LinkedList<>();
distance++;
while (!queue.isEmpty()) {
String top = queue.poll();
ArrayList<String> wordsWithinDistance =
getWordsWithinDistance(wordSet, top);
if (wordsWithinDistance.contains(endWord)) {
return distance;
}
queue2.addAll(wordsWithinDistance);
}
queue = queue2;
}
return 0;
}public ArrayList<String> getWordsWithinDistance(Set<String> wordSet,
String word) {
ArrayList<String> results = new ArrayList<>();
char[] wordCharArr = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
char oriChar = wordCharArr[i];
for (char c = 'a'; c <= 'z'; c++) {
if (c == oriChar) {
continue;
}
wordCharArr[i] = c;
String newStr = new String(wordCharArr);
if (wordSet.contains(newStr)) {
results.add(newStr);
wordSet.remove(newStr);
}
}
wordCharArr[i] = oriChar;
}
return results;
}Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
cog
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
cog
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Example:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
hit
hot
dot
lot
dog
log
cog
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
public List<List<String>> findLadders(String beginWord, String endWord,
List<String> wordList) {
Set<String> wordSet = new HashSet<>();
for(String aWord: wordList) {
wordSet.add(aWord);
}
List<List<String>> results = new ArrayList<>();
HashMap<String, ArrayList<String>> preList = new HashMap<>();
Queue<String> queue = new LinkedList<>();
queue.offer(beginWord);
Set<String> visited = new HashSet<>();
visited.add(beginWord); while (!queue.isEmpty() && !wordList.isEmpty()) {
Set<String> queue2 = new HashSet<>();
boolean isFinished = false;
while (!queue.isEmpty()) {
String top = queue.poll();
Set<String> wordsWithinDistance =
getWordsWithinDistance(wordList, top);
for (String word : wordsWithinDistance) {
if (word.equals(endWord)) {
isFinished = true;
}
if (!visited.contains(word)) {
updatePreList(preList, word, top);
queue2.add(word);
}
}
}
visited.addAll(queue2);
if (isFinished) {
getPaths(results, preList, new ArrayList<String>(), endWord);
break;
}
queue.addAll(queue2);
}
return results;
}public void updatePreList(HashMap<String, ArrayList<String>> preList,
String cur, String pre) {
if (!preList.containsKey(cur)) {
preList.put(cur, new ArrayList<String>());
}
preList.get(cur).add(pre);
}
public Set<String> getWordsWithinDistance(Set<String> wordSet, String word) {
Set<String> results = new HashSet<>();
char[] wordCharArr = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
char oriChar = wordCharArr[i];
for (char c = 'a'; c <= 'z'; c++) {
if (c == oriChar) {
continue;
}
wordCharArr[i] = c;
String newStr = new String(wordCharArr);
if (wordSet.contains(newStr)) {
results.add(newStr);
}
}
wordCharArr[i] = oriChar;
}
return results;
}public void getPaths(List<List<String>> paths,
HashMap<String, ArrayList<String>> preList,
List<String> curPath,
String end) {
if (!preList.containsKey(end)) {
curPath.add(end);
Collections.reverse(curPath);
paths.add(curPath);
return;
}
for (String pre : preList.get(end)) {
List<String> newPath = new ArrayList<String>(curPath);
newPath.add(end);
getPaths(paths, preList, newPath, pre);
}
}Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
X X X X
X O O X
X X O X
X O X X
X X X X
X X X X
X X X X
X O X X
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
public void solve(char[][] board) {
if (board.length == 0 || board[0].length == 0)
return;
for (int j = 0; j < board[0].length; j++) {
search(board, 0, j);
search(board, board.length-1, j);
}
for (int i = 0; i < board.length; i++) {
search(board, i, 0);
search(board, i, board[0].length-1);
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
board[i][j] = board[i][j] == 'F' ? 'O' : 'X';
}
}
}Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
// BFS
public void search(char[][] board, int x, int y) {
if (board[x][y] == 'X') {
return;
}
Queue<Integer> queue = new LinkedList<Integer>();
int xLen = board.length, yLen = board[0].length;
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, 1, 0, -1};
queue.offer(x * yLen + y);
board[x][y] = 'F';
while (!queue.isEmpty()) {
int temp = queue.poll();
for (int i = 0; i < 4; i++) {
int nx = temp / yLen + dx[i], ny = temp % yLen + dy[i];
if (nx >= 0 && nx < xLen && ny >= 0 && ny < yLen
&& board[nx][ny] == 'O') {
board[nx][ny] = 'F';
queue.offer(nx * yLen + ny);
}
}
}
}Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
// DFS
public void search(char[][] board, int i, int j) {
if (board[i][j] != 'O')
return;
board[i][j] = 'F';
if (i > 1)
search(board, i-1, j);
if (i < board.length - 2)
search(board, i+1, j);
if (j > 1)
search(board, i, j-1);
if (j < board[i].length - 2)
search(board, i, j+1);
}Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses ( and ).
We talk about this problem using DFS
How to use BFS?
Starting from the longest, generate all possible subString and push them into the queue
public List<String> removeInvalidParentheses(String s) {
List<String> result = new ArrayList<>();
Queue<String> queue = new LinkedList<>();
Set<String> checked = new HashSet<>();
boolean found = false;
int max = 0;
queue.add(s);
while (!queue.isEmpty()) {
String t = queue.remove();
if (isValid(t)) {
found = true;
if (t.length() >= max && !result.contains(t)) {
max = t.length();
result.add(t);
}
}
if (found) continue;
for (int i = 0; i < t.length(); i ++) {
String sub1 = t.substring(0, i);
String sub2 = t.substring(i + 1, t.length());
String temp = sub1.concat(sub2);
if (!checked.contains(temp)) {
queue.add(temp);
checked.add(temp);
}
}
}
return result;
}public boolean isValid(String s) {
int count = 0;
for(int i = 0; i < s.length(); i ++){
if (s.charAt(i) == '(') count ++;
else if (s.charAt(i) == ')') {
if (count == 0) return false;
else count --;
}
}
return (count == 0);
}