from collections import deque
# Creating a queue
queue = deque()
# Adding elements to the queue
queue.append('element1') # Similar to offer in Java
queue.append('element2')
# Removing elements from the queue
element = queue.popleft() # Similar to poll in Java; use pop() for a stack
if not queue:
print("Queue is empty")
# Peeking at the front of the queue
if queue:
front = queue[0] # Similar to peek in Java
print("Front element:", front)
else:
print("Queue is empty, nothing to peek")
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.
def level_order_traversal(root):
queue = deque([root]) # Initialize the queue with the root
while queue:
top = queue.popleft() # Pop from the front of the queue
# visit top (can be replaced with any operation)
print(top.val) # Example visit operation
if top.left:
queue.append(top.left) # Add left child to queue if exists
if top.right:
queue.append(top.right) # Add right child to queue if exists
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;
}
Given a binary tree, return its level order traversal.
def levelOrder(root):
results = []
queue = []
if root is not None:
queue.append(root)
while len(queue) > 0:
oneResult = []
queue2 = []
while len(queue) > 0:
top = queue.pop(0)
if top.left is not None:
queue2.append(top.left)
if top.right is not None:
queue2.append(top.right)
oneResult.append(top.val)
results.append(oneResult)
queue = queue2
return results
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;
}
def levelOrder(root):
if not root:
return []
results = []
queue = []
queue.append(root)
queue.append(None)
oneResult = []
while len(queue) > 0:
top = queue.pop(0)
if top is None:
results.append(oneResult)
if len(queue) > 0:
queue.append(None)
oneResult = []
else:
if top.left is not None:
queue.append(top.left)
if top.right is not None:
queue.append(top.right)
oneResult.append(top.val)
return results
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
int size = 1;
int nextSize = 0;
if (root != null) {
queue.offer(root);
}
List<Integer> oneResult = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode top = queue.poll();
if (top.left != null) {
queue.offer(top.left);
nextSize ++;
}
if (top.right != null) {
queue.offer(top.right);
nextSize ++;
}
oneResult.add(top.val);
size --;
if (size == 0) {
results.add(oneResult);
oneResult = new ArrayList<>();
size = nextSize;
nextSize = 0;
}
}
return results;
}
def levelOrder(root):
results = []
queue = []
size = 1
nextSize = 0
if root is not None:
queue.append(root)
oneResult = []
while queue:
top = queue.pop(0)
if top.left is not None:
queue.append(top.left)
nextSize += 1
if top.right is not None:
queue.append(top.right)
nextSize += 1
oneResult.append(top.val)
size -= 1
if size == 0:
results.append(oneResult)
oneResult = []
size = nextSize
nextSize = 0
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;
}
def zigzagLevelOrder(root):
results = []
queue = []
if root is not None:
queue.append(root)
isOdd = True
while len(queue) > 0:
oneResult = []
queue2 = []
while len(queue) > 0:
top = queue.pop(0)
if top.left is not None:
queue2.append(top.left)
if top.right is not None:
queue2.append(top.right)
oneResult.append(top.val)
if not isOdd:
oneResult.reverse()
results.append(oneResult)
isOdd = not isOdd
queue = queue2
return results
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> results = new ArrayList<>();
if (root == null)
return results;
Stack<TreeNode> stack = new Stack<>();
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;
}
3 / \ 9 20 / \ 15 7
[
[3],
[20,9],
[15,7]
]
def zigzagLevelOrder(root):
results = []
if root is None:
return results
stack = []
stack.append(root)
isOdd = True
while len(stack) > 0:
oneResult = []
stack2 = []
while len(stack) > 0:
top = stack.pop()
if not isOdd:
if top.right is not None:
stack2.append(top.right)
if top.left is not None:
stack2.append(top.left)
else:
if top.left is not None:
stack2.append(top.left)
if top.right is not None:
stack2.append(top.right)
oneResult.append(top.val)
results.append(oneResult)
stack = stack2
isOdd = not 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) {
queue2.offer(top.left);
}
if (top.right != null) {
queue2.offer(top.right);
}
}
queue = queue2;
}
return leftValue;
}
def findBottomLeftValue(root):
queue = []
queue.append(root)
leftValue = 0
isFirst = False
while queue:
isFirst = True
queue2 = []
while queue:
top = queue.pop(0)
if isFirst:
leftValue = top.val
isFirst = False
if top.left:
queue2.append(top.left)
if top.right:
queue2.append(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;
}
def minDepth(root):
if root is None:
return 0
queue = []
queue.append(root)
queue.append(None)
minDepth = 1
while len(queue) > 0:
top = queue.pop(0)
if top is None:
minDepth += 1
queue.append(None)
continue
if top.left is None and top.right is None:
return minDepth
if top.left is not None:
queue.append(top.left)
if top.right is not None:
queue.append(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;
}
BFS vs DFS, which is better?
def minDepth(root):
if root is None:
return 0
queue = []
queue.append(root)
minDepth = 1
while len(queue) > 0:
queue2 = []
while len(queue) > 0:
top = queue.pop(0)
if top.left is None and top.right is None:
return minDepth
if top.left is not None:
queue2.append(top.left)
if top.right is not None:
queue2.append(top.right)
minDepth += 1
queue = queue2
return minDepth
We can solve using DFS
We can also do it in BFS
public static boolean solveMaze(char[][] maze,
int startX, int startY, int targetX, int targetY,
boolean[][] visited) {
Queue<Integer> queue = new LinkedList<>();
int xLen = maze.length, yLen = maze[0].length;
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, 1, 0, -1};
queue.offer(startX * yLen + startY);
visited[startX][startY] = true;
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 == targetX && ny == targetY) {
return true;
}
if (nx >= 0 && nx < xLen && ny >= 0 && ny < yLen
&& maze[nx][ny] == 'O' && !visited[nx][ny]) {
visited[nx][ny] = true;
queue.offer(nx * yLen + ny);
}
}
}
return false;
}
Queue setup:
2 dimension ->
1 dimension
from collections import deque
def solveMaze(maze, startX, startY, targetX, targetY, visited):
queue = deque()
xLen, yLen = len(maze), len(maze[0])
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
queue.append(startX * yLen + startY)
visited[startX][startY] = True
while queue:
temp = queue.popleft()
for i in range(4):
nx = temp // yLen + dx[i]
ny = temp % yLen + dy[i]
if nx == targetX and ny == targetY:
return True
if 0 <= nx < xLen and 0 <= ny < yLen and maze[nx][ny] == 'O' and not visited[nx][ny]:
visited[nx][ny] = True
queue.append(nx * yLen + ny)
return False
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.
the biggest difference: This time the ball not always goes only 1 step.
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;
}
def shortestDistance(self, maze, start, dest):
row = len(maze)
col = len(maze[0])
distance = [[float('inf') for _ in range(col)] for _ in range(row)]
dx = [1, 0, 0, -1]
dy = [0, -1, 1, 0]
queue = []
queue.append(Pair(start[0], start[1]))
distance[start[0]][start[1]] = 0
while queue:
current = queue.pop(0)
for i in range(4):
x = current.x
y = current.y
dist = distance[x][y]
while x >= 0 and x < row and y >= 0 and y < col and maze[x][y] == 0:
x += dx[i]
y += dy[i]
dist += 1
x -= dx[i]
y -= dy[i]
dist -= 1
if distance[x][y] > dist:
distance[x][y] = dist
if x != dest[0] or y != dest[1]:
queue.append(Pair(x, y))
res = distance[dest[0]][dest[1]]
return -1 if res == float('inf') else res
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
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;
}
def findShortestWay(self, maze, ball, hole):
row = len(maze)
col = len(maze[0])
dx = [1, 0, 0, -1]
dy = [0, -1, 1, 0]
dir = ["d", "l", "r", "u"]
distance = [[float('inf')] * col for _ in range(row)]
distance[ball[0]][ball[1]] = 0
queue = [(ball[0], ball[1])]
path = [[""] * col for _ in range(row)]
path[ball[0]][ball[1]] = ""
while queue:
cur = queue.pop(0)
for i in range(4):
x, y = cur[0], cur[1]
dist = distance[x][y]
currentPath = path[x][y]
while x >= 0 and x < row and y >= 0 and y < col and maze[x][y] == 0 and (x != hole[0] or y != hole[1]):
x += dx[i]
y += dy[i]
dist += 1
if x != hole[0] or y != hole[1]:
x -= dx[i]
y -= dy[i]
dist -= 1
newPath = currentPath + dir[i]
if distance[x][y] > dist or (distance[x][y] == dist and path[x][y] > newPath):
distance[x][y] = dist
path[x][y] = newPath
if x != hole[0] or y != hole[1]:
queue.append((x, y))
result = path[hole[0]][hole[1]]
return "impossible" if distance[hole[0]][hole[1]] == float('inf') else 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 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);
}
}
wordCharArr[i] = oriChar;
}
return results;
}
def ladderLength(beginWord, endWord, wordList):
wordSet = set(wordList)
queue = []
queue.append(beginWord)
visited = set()
visited.add(beginWord)
distance = 1
while queue:
queue2 = []
distance += 1
while queue:
top = queue.pop(0)
wordsWithinDistance = getWordsWithinDistance(wordSet, top)
for word in wordsWithinDistance:
if word == endWord:
return distance
if word not in visited:
queue2.append(word)
visited.add(word)
queue = queue2
return 0
def getWordsWithinDistance(wordSet, word):
results = []
wordCharArr = list(word)
for i in range(len(word)):
oriChar = wordCharArr[i]
for c in range(ord('a'), ord('z')+1):
if c == ord(oriChar):
continue
wordCharArr[i] = chr(c)
newStr = ''.join(wordCharArr)
if newStr in wordSet:
results.append(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;
}
访问过的可以在wordSet删掉, 已经在results保存, 下次也不需要再check
def ladderLength(beginWord, endWord, wordList):
wordSet = set(wordList)
queue = [beginWord]
distance = 1
while queue and wordSet:
queue2 = []
distance += 1
while queue:
top = queue.pop(0)
wordsWithinDistance = getWordsWithinDistance(wordSet, top)
if endWord in wordsWithinDistance:
return distance
queue2.extend(wordsWithinDistance)
queue = queue2
return 0
def getWordsWithinDistance(wordSet, word):
results = []
wordCharArr = list(word)
for i in range(len(word)):
oriChar = wordCharArr[i]
for c in 'abcdefghijklmnopqrstuvwxyz':
if c == oriChar:
continue
wordCharArr[i] = c
newStr = ''.join(wordCharArr)
if newStr in wordSet:
results.append(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;
}
def findLadders(beginWord, endWord, wordList):
wordSet = set(wordList)
results = []
preList = {}
queue = [beginWord]
visited = set()
visited.add(beginWord)
while queue and wordList:
queue2 = set()
isFinished = False
while queue:
top = queue.pop(0)
wordsWithinDistance = getWordsWithinDistance(wordList, top)
for word in wordsWithinDistance:
if word == endWord:
isFinished = True
if word not in visited:
updatePreList(preList, word, top)
queue2.add(word)
visited.update(queue2)
if isFinished:
getPaths(results, preList, [], endWord)
break
queue.extend(queue2)
return results
def updatePreList(preList, cur, pre):
if cur not in preList:
preList[cur] = []
preList[cur].append(pre)
def getWordsWithinDistance(wordSet, word):
results = set()
wordCharArr = list(word)
for i in range(len(word)):
oriChar = wordCharArr[i]
for c in 'abcdefghijklmnopqrstuvwxyz':
if c == oriChar:
continue
wordCharArr[i] = c
newStr = ''.join(wordCharArr)
if newStr in wordSet:
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);
}
}
def getPaths(paths, preList, curPath, end):
if end not in preList:
curPath.append(end)
curPath.reverse()
paths.append(curPath)
return
for pre in preList[end]:
newPath = curPath.copy()
newPath.append(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);
}
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.
def solve(board):
if len(board) == 0 or len(board[0]) == 0:
return
for j in range(len(board[0])):
search(board, 0, j)
search(board, len(board)-1, j)
for i in range(len(board)):
search(board, i, 0)
search(board, i, len(board[0])-1)
for i in range(len(board)):
for j in range(len(board[0])):
board[i][j] = 'O' if board[i][j] == 'F' else '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
def search(board, x, y):
if board[x][y] == 'X':
return
queue = []
xLen = len(board)
yLen = len(board[0])
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
queue.append(x * yLen + y)
board[x][y] = 'F'
while queue:
temp = queue.pop(0)
for i in range(4):
nx = temp // yLen + dx[i]
ny = temp % yLen + dy[i]
if nx >= 0 and nx < xLen and ny >= 0 and ny < yLen and board[nx][ny] == 'O':
board[nx][ny] = 'F'
queue.append(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
def search(board, i, j):
if board[i][j] != 'O':
return
board[i][j] = 'F'
if i > 1:
search(board, i-1, j)
if i < len(board) - 2:
search(board, i+1, j)
if j > 1:
search(board, i, j-1)
if j < len(board[i]) - 2:
search(board, i, j+1)