class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root==null)return res;
Deque<TreeNode> q=new ArrayDeque<>();
q.addLast(root);
while(!q.isEmpty()){//一层一层的来
int size = q.size();//第一层的大小
int v=0;
while(size>0){//从第第一层来获取第二层
TreeNode node = q.pollFirst();//将第一层的元素依次除掉
size--;
v=node.val;//最后一次更新一定是这一层最右边的元素
if(node.left!=null)q.addLast(node.left);//先左
if(node.right!=null)q.addLast(node.right);//再右
}
res.add(v);
}
return res;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void flatten(TreeNode root) {//传入一棵树 将这颗树变为右斜线树
//如果root == null 那么不用变 直接返回
if(root == null)return ;
//如果树只有一个节点 也不用变换 直接返回
if(root.left==null && root.right == null)return;
//如果根没有左子树 那么就需要把右子树变为线条型后返回
if(root.left == null){
flatten(root.right);
return ;
}else{//如果根节点左右子树都有
//那么就都要变成线条型
flatten(root.left);
flatten(root.right);
//把右子树拼接到左子树的右下角
TreeNode temp = root.left;
while(temp.right!=null){
temp = temp.right;
}
temp.right = root.right;
//再把左子树移动到右边变为root的右子树
root.right = root.left;
//最后把root的左子树置为null
root.left = null;
return ;
}
}
}
//写法1 BFS
class Solution {
public int numIslands(char[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] dirs = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};//上下左右
int res = 0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
//找到岛屿格数
if(grid[i][j] == '1'){
res ++;
Deque<int[]> q = new ArrayDeque<>();
q.addLast(new int[]{i,j});
//更新状态 防止重复访问
grid[i][j] = '2';
while(!q.isEmpty()){
int[] poll = q.poll();
//将附近的岛屿加入
for(int[] d:dirs){
int x = poll[0] + d[0];
int y = poll[1] + d[1];
if(x>=0&&x<n&&y>=0&&y<m&&grid[x][y]=='1'){
q.addLast(new int[]{x,y});
grid[x][y] = '2';//标记为2
}
}
}
}
}
}
return res;
}
}
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
//找到岛屿格
dfs(grid, i, j);
//记录答案
count++;
}
}
}
return count;
}
public void dfs(char[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != '1') return;
grid[i][j] = '2';//更新状态
dfs(grid, i + 1, j);//向下移动
dfs(grid, i - 1, j);//向上移动
dfs(grid, i, j + 1);//向右移动
dfs(grid, i, j - 1);//向左移动
}
}
class Solution {
public int orangesRotting(int[][] grid) {
int M = grid.length;
int N = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
int count = 0; // count 表示新鲜橘子的数量
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
if (grid[r][c] == 1) {
count++;
} else if (grid[r][c] == 2) {
queue.add(new int[]{r, c});
}
}
}
int round = 0; // round 表示腐烂的轮数,或者分钟数
while (count > 0 && !queue.isEmpty()) {
round++;
int n = queue.size();
for (int i = 0; i < n; i++) {
int[] orange = queue.poll();
int r = orange[0];
int c = orange[1];
if (r-1 >= 0 && grid[r-1][c] == 1) {
grid[r-1][c] = 2;
count--;
queue.add(new int[]{r-1, c});
}
if (r+1 < M && grid[r+1][c] == 1) {
grid[r+1][c] = 2;
count--;
queue.add(new int[]{r+1, c});
}
if (c-1 >= 0 && grid[r][c-1] == 1) {
grid[r][c-1] = 2;
count--;
queue.add(new int[]{r, c-1});
}
if (c+1 < N && grid[r][c+1] == 1) {
grid[r][c+1] = 2;
count--;
queue.add(new int[]{r, c+1});
}
}
}
if (count > 0) {
return -1;
} else {
return round;
}
}
}
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
List<Integer> remain = new ArrayList<>();
for(int i = 0; i < n; i++){
remain.add(nums[i]);
}
dfs(ans, n, remain, new ArrayList<Integer>());
return ans;
}
public void dfs(List<List<Integer>> ans, int n, List<Integer> remain, List<Integer> combination){
if(combination.size() == n){
ans.add(new ArrayList<Integer>(combination));
return;
}
for(int i = 0; i < remain.size(); i++){
List<Integer> temp = new ArrayList<>(remain);
combination.add(temp.get(i));//这个数字打头
temp.remove(i);//防止重复选择
dfs(ans, n, temp, combination);
combination.remove(combination.size() - 1);
}
}
}
class Solution {
List<Integer> t = new ArrayList<Integer>();
List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> subsets(int[] nums) {
int n = nums.length;
for (int mask = 0; mask < (1 << n); ++mask) {
t.clear();
for (int i = 0; i < n; ++i) {
if ((mask & (1 << i)) != 0) {
t.add(nums[i]);
}
}
ans.add(new ArrayList<Integer>(t));
}
return ans;
}
}
class Solution {
private static final String[] MAPPING = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private final List<String> ans = new ArrayList<>();
private char[] digits;
private char[] path;
public List<String> letterCombinations(String digits) {
int n = digits.length();
if(n==0)return ans;
this.digits = digits.toCharArray();
path = new char[n];//path长度一开始就是n 不是空数组
dfs(0);
return ans;
}
private void dfs(int i){
if(i == digits.length){
ans.add(new String(path));
return ;
}
for(char c:MAPPING[digits[i]-'0'].toCharArray()){
path[i] = c;//直接覆盖
dfs(i+1);
}
}
}
class Solution {
private List<String> res;
public List<String> generateParenthesis(int n) {
res = new ArrayList<>();
StringBuilder sb = new StringBuilder();
doit(n,0,sb);
return res;
}
private void doit(int k,int stack,StringBuilder s){
//如果剩余括号为0 且栈为空 则添加至答案
if(k==0 && stack==0)res.add(new String(s));
//否则则有两种做法
//第一种做法 剩余括号出栈
if(k!=0){
doit(k-1,stack+1,s.append('('));
s.deleteCharAt(s.length()-1);//回溯
}
//第二种做法 括号出栈
if(stack!=0){
doit(k,stack-1,s.append(')'));
s.deleteCharAt(s.length()-1);//回溯
}
}
}
class Solution {
void dfs(List<Integer>state,int target,int[] choices,int start,List<List<Integer>>res){
//子集和为target的时候记录下来
if(target == 0){
res.add(new ArrayList<>(state));
return ;
}
//遍历所有选择
//从start开始遍历 避免形成重复的子集
for(int i = start;i<choices.length;i++){
//小小的剪枝
//因为数组已经排序 后面的更大
if(target - choices[i]<0)break;
state.add(choices[i]);
//进行下一轮选择
dfs(state,target-choices[i],choices,i,res);//排序加上可以从这个点作为start 可以重复利用这个元素
//回溯
state.remove(state.size()-1);
}
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> state = new ArrayList<>();//子集状态
Arrays.sort(candidates);
int start = 0;
List<List<Integer>> res = new ArrayList<>();//结果列表
dfs(state,target,candidates,start,res);
return res;
}
}