广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。
而深度优先搜索在得到一个新节点时立即对新节点进行遍历,直到没有新节点了,此时返回,然后继续以上步骤。
从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种 可达性 问题。
DFS 与回溯法会省去一个回退的过程
在程序实现 DFS 时需要考虑以下问题:
leetcode 695 岛屿的最大面积(中等)
给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)
示例 1:
[
[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]
]
对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。
示例 2:
[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。
注意: 给定的矩阵grid 的长度和宽度都不超过 50。
题解:
class Solution {
private int res;
private int m, n;
private boolean[][] used;
private int[][] nextStep = {{1,0}, {-1,0}, {0,1}, {0,-1}};
public int maxAreaOfIsland(int[][] grid) {
if(grid.length==0 || grid[0].length==0){
return 0;
}
m = grid.length;
n = grid[0].length;
used = new boolean[m][n];
for(int i=0; i=0 && i=0 && j
leetcode 200 岛屿数量(中等)
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
题解:
class Solution {
private int res;
private int m, n;
private boolean[][] used;
private int[][] dist = {{1,0}, {-1,0}, {0,1}, {0,-1}};
public int numIslands(char[][] grid) {
if(grid.length == 0 || grid[0].length==0){
return 0;
}
m = grid.length;
n = grid[0].length;
used = new boolean[m][n];
for(int i=0; i=0 && i=0 && j
leetcode 547 朋友圈(中等)
班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
示例 1:
输入:
[[1,1,0],
[1,1,0],
[0,0,1]]
输出: 2
说明:已知学生0和学生1互为朋友,他们在一个朋友圈。
第2个学生自己在一个朋友圈。所以返回2。
示例 2:
输入:
[[1,1,0],
[1,1,1],
[0,1,1]]
输出: 1
说明:已知学生0和学生1互为朋友,学生1和学生2互为朋友,所以学生0和学生2也是朋友,所以他们三个在一个朋友圈,返回1。
注意:
题解:
class Solution {
private int res;
private int n;
private boolean[] used;
public int findCircleNum(int[][] M) {
if(M.length == 0){
return 0;
}
n = M.length;
used = new boolean[n];
// 寻找没有建立盆友圈的人
for(int i=0; i
leetcode 417 太平洋大西洋水流问题(中等)
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。
规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。
请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
提示:
示例:
给定下面的 5x5 矩阵:
太平洋 ~ ~ ~ ~ ~
~ 1 2 2 3 5 *
~ 3 2 3 4 4 *
~ 2 4 5 3 1 *
~ 6 7 1 4 5 *
~ 5 1 1 2 4 *
* * * * * 大西洋
返回:
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中加粗的单元).
题解:
class Solution {
private ArrayList> res = new ArrayList>();
private int m, n;
private int[][] dist = {{0,1}, {0,-1}, {1,0}, {-1,0}};
public List> pacificAtlantic(int[][] matrix) {
if(matrix.length==0 || matrix[0].length==0){
return res;
}
m = matrix.length;
n = matrix[0].length;
boolean[][] canReachA = new boolean[m][n];
boolean[][] canReachP = new boolean[m][n];
for(int i=0; i list = new ArrayList<>();
list.add(i);
list.add(j);
res.add(list);
}
}
}
return res;
}
private boolean inArea(int i, int j){
return i>=0 && i=0 && j=matrix[i][j]){
dfs(matrix, nextI, nextJ, canReach);
}
}
}
}
leetcode 130 被围绕的区域(中等)
给定一个二维的矩阵,包含 ‘X’ 和 ‘O’(字母 O)。
找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。
示例:
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
解释:
被围绕的区间不会存在于边界上,换句话说,任何边界上的 ‘O’ 都不会被填充为 ‘X’。 任何不在边界上,或不与边界上的 ‘O’ 相连的 ‘O’ 最终都会被填充为 ‘X’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
题解:
class Solution {
private int m, n;
private int[][] dist = {{1,0},{-1,0},{0,1},{0,-1}};
public void solve(char[][] board) {
if(board.length==0 || board[0].length == 0){
return;
}
m = board.length;
n = board[0].length;
for(int i=0; i=0 && i=0 && j
Backtracking(回溯)属于 DFS。
因为 Backtracking 不是立即返回,而要继续求解,因此在程序实现时,需要注意对元素的标记问题:
leetcode 46 全排列(中等)
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
private boolean[] used;
public List> permute(int[] nums) {
int n = nums.length;
if(n==0){
return res;
}
used = new boolean[n];
LinkedList list = new LinkedList<>();
sub(nums, 0, list);
return res;
}
private void sub(int[] nums, int index, LinkedList list){
if(index == nums.length){
res.add(new LinkedList(list));
return;
}
for(int i=0; i
leetcode 47 全排列II(中等)
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
题解:
数组元素含有相同的元素,进行排列时就有可能出现重复的排列,要求重复的排列只返回一个。
在实现上,要先排序,然后在添加一个元素时,判断这个元素是否等于前一个元素,如果等于,并且前一个元素还未访问,那么就跳过这个元素。
class Solution {
private ArrayList> res = new ArrayList>();
private boolean[] used;
public List> permuteUnique(int[] nums) {
int n = nums.length;
if(n==0){
return res;
}
used = new boolean[n];
// 去重操作,需要先排个序
Arrays.sort(nums);
LinkedList list = new LinkedList<>();
sub(nums, 0, list);
return res;
}
private void sub(int[] nums, int index, LinkedList list){
if(index == nums.length){
res.add(new LinkedList(list));
return;
}
for(int i=0; i0 && nums[i]==nums[i-1] && !used[i-1]){
continue;
}
used[i] = true;
list.addLast(nums[i]);
sub(nums, index+1, list);
used[i] = false;
list.removeLast();
}
}
return;
}
}
401
leetcode 17 电话号码的组合(中等)
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
题解:
class Solution {
private static final String[] numMap = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private ArrayList res = new ArrayList<>();
public List letterCombinations(String digits) {
if(digits.length()==0){
return res;
}
sub(digits, 0, "");
return res;
}
// 处理digits的第index个字符,0 ~ index-1 的结果存放在subStr中
private void sub(String digits, int index, String subStr){
if(index == digits.length()){
res.add(subStr);
return;
}
String s = numMap[digits.charAt(index)-'2'];
for(int i=0; i
leetcode 77 组合(中等)
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
public List> combine(int n, int k) {
if(k>n || k==0 || n==0){
return res;
}
LinkedList list = new LinkedList<>();
sub(n, k, 1, 0, list);
return res;
}
private void sub(int n, int k, int start, int index, LinkedList list){
if(index == k){
res.add(new LinkedList(list));
return;
}
// 剪枝 i<=n ---> i<=n-(k-index)+1
for(int i=start; i<=(n-(k-index)+1); i++){
list.addLast(i);
sub(n, k, i+1, index+1, list); // 注意,这里start=i+1 而不是start+1
list.removeLast();
}
return;
}
}
leetcode 401 二进制手表 (简单)
二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59)。
每个 LED 代表一个 0 或 1,最低位在右侧。
例如,上面的二进制手表读取 “3:25”。
给定一个非负整数 n 代表当前 LED 亮着的数量,返回所有可能的时间。
案例:
输入: n = 1
返回: [“1:00”, “2:00”, “4:00”, “8:00”, “0:01”, “0:02”, “0:04”, “0:08”, “0:16”, “0:32”]
注意事项:
题解:
“n个数中选k个数” 的变形问题 可以理解为从10个位置中取num个位置的组合问题
class Solution {
private List res = new ArrayList();
public List readBinaryWatch(int num) {
int[] stat = new int[10];
sub(num, 0, 0, stat);
return res;
}
// “n个数中选k个数” 的变形问题
// 可以理解为从10个位置中取num个位置的组合问题
// int[] stat 的前四位表示小时,后六位表示分钟
// 通过回溯选出所有的组合
private void sub(int num, int start, int cnt, int[] stat){
if(cnt == num){
int hour = stat[0]*8+stat[1]*4+stat[2]*2+stat[3];
int minu = stat[4]*32+stat[5]*16+stat[6]*8+stat[7]*4+stat[8]*2+stat[9];
if(hour<12 && minu<60){
String s = String.format("%d:%02d", hour, minu);
res.add(s);
}
return;
}
// 剪枝 i<=9 ----> i<=9-(num-cnt)+1
for(int i=start; i<=(9-(num-cnt)+1); i++){
stat[i] = 1;
sub(num, i+1, cnt+1, stat);
stat[i] = 0;
}
return;
}
}
leetcode 39 组合总和(中等)
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
public List> combinationSum(int[] candidates, int target) {
if(candidates.length == 0){
return res;
}
LinkedList list = new LinkedList<>();
sub(candidates, target, 0, 0, list);
return res;
}
private void sub(int[] nums, int target, int cur, int start, LinkedList list){
if(cur == target){
res.add(new LinkedList(list));
return;
}
for(int i=start; i
leetcode 40 组合总和II (中等)
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
private boolean[] used;
public List> combinationSum2(int[] candidates, int target) {
if(candidates.length == 0){
return res;
}
used = new boolean[candidates.length];
// 有重复数字 去重, 先排个序
Arrays.sort(candidates);
LinkedList list = new LinkedList<>();
sub(candidates, target, 0, 0, list);
return res;
}
private void sub(int[] arr, int target, int cur, int start, LinkedList list){
if(cur == target){
res.add(new LinkedList(list));
return;
}
for(int i=start; i0 && arr[i]==arr[i-1] && !used[i-1]){
continue;
}
used[i] = true;
list.addLast(arr[i]);
sub(arr, target, cur+arr[i], i+1, list);
list.removeLast();
used[i] = false;
}
}
return;
}
}
leetcode 216 组合总和III(中等)
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
public List> combinationSum3(int k, int n) {
if(k==0 || n==0 || n list = new LinkedList<>();
sub(k, n, 0, 0, 1, list);
return res;
}
private void sub(int k, int n, int index, int cur, int start, LinkedList list){
if(index == k){
if(cur == n){
res.add(new LinkedList(list));
}
return;
}
// 剪枝1: i<=9 ---> i<=9-(k-index)+1
for(int i=start; i<=(9-(k-index)+1); i++){
if(cur+i<=n){ // 剪枝2
list.addLast(i);
sub(k, n, index+1, cur+i, i+1, list);
list.removeLast();
}
}
return;
}
}
leetcode 78 子集(中等)
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明: 解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
public List> subsets(int[] nums) {
int n = nums.length;
if(n==0){
res.add(new LinkedList());
return res;
}
LinkedList list = new LinkedList<>();
sub(nums, 0, list);
res.add(new LinkedList());
return res;
}
private void sub(int[] nums, int start, LinkedList list){
for(int i=start; i(list));
sub(nums, i+1, list);
list.removeLast();
}
return;
}
}
leetcode 90 子集II(中等)
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明: 解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
private boolean[] used;
public List> subsetsWithDup(int[] nums) {
int n = nums.length;
if(n==0){
res.add(new LinkedList());
return res;
}
used = new boolean[n];
// 含有重复元素的去重,先排个序
Arrays.sort(nums);
LinkedList list = new LinkedList<>();
sub(nums, 0, list);
res.add(new LinkedList());
return res;
}
private void sub(int[] nums, int start, LinkedList list){
for(int i=start; i0 && nums[i]==nums[i-1] && !used[i-1]){
continue;
}
used[i] = true;
list.addLast(nums[i]);
res.add(new LinkedList(list));
sub(nums, i+1, list);
used[i] = false;
list.removeLast();
}
return;
}
}
leetcode 79 单词搜索(中等)
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true.
给定 word = “SEE”, 返回 true.
给定 word = “ABCB”, 返回 false.
题解:
class Solution {
private int m,n;
private boolean[][] used;
private int[][] dir = {{1,0}, {-1,0}, {0,1},{0,-1}};
public boolean exist(char[][] board, String word) {
if(board.length==0 || board[0].length==0){
return false;
}
m = board.length;
n = board[0].length;
used = new boolean[m][n];
for(int i=0; i=0 && i=0 && j
leetcode 37 解数独(困难)
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
Note:
题解:
class Solution {
private boolean[][] rowUsed = new boolean[9][10]; // rowUsed[i][j]=true 表示第i行已经出现过数字j
private boolean[][] colUsed = new boolean[9][10];
private boolean[][] blockUsed = new boolean[9][10]; // 通过 i/3*3+j/3 将(i,j)映射到 9 个块中
public void solveSudoku(char[][] board) {
// 初始化 rowUsed, colUsed, blockUsed
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
if(board[i][j] != '.'){
int num = board[i][j] - '0';
rowUsed[i][num] = true;
colUsed[j][num] = true;
blockUsed[i/3*3+j/3][num] = true;
}
}
}
sub(board, 0, 0);
}
private boolean sub(char[][] board, int i, int j){
//根据传入的位置(i,j)开始 从左到右,从上到下 寻找未填充的位置 直至填充完
while(board[i][j]!='.'){
if(++j>8){
j=0;
i++;
}
if(i>8){
return true;
}
}
// 尝试给该空位填充1~9,不成功则回退
for(int k=1; k<=9; k++){
if(!rowUsed[i][k] && !colUsed[j][k] && !blockUsed[i/3*3+j/3][k]){
board[i][j] = (char)('0'+k);
rowUsed[i][k] = true;
colUsed[j][k] = true;
blockUsed[i/3*3+j/3][k] = true;
// 若下一个空位可以填充,则当前空位不需回退
if(sub(board, i, j)){
return true;
}else{
// 回退
board[i][j] = '.';
rowUsed[i][k] = false;
colUsed[j][k] = false;
blockUsed[i/3*3+j/3][k] = false;
}
}
}
return false;
}
}
leetcode 51 N皇后(困难)
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出:
[
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],
["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解释: 4 皇后问题存在两个不同的解法。
题解:
class Solution {
private boolean[] rowUsed, colUsed, diag1Used, diag2Used;
private ArrayList> res = new ArrayList>();
private int n;
public List> solveNQueens(int n) {
this.n = n;
// 同一条主对角线上的位置坐标和i+j相等, 同一条反对角线上的位置坐标差i-j相等,为了保证为正(用作数组下标)需加上(n-1)
// 当尝试在第i行,第j列放置皇后时,需要保证在第i行,第j列, 坐标和为i+j的主对角线,以及坐标差为i-j+n-1的反对角线上不存在皇后
rowUsed = new boolean[n];
colUsed = new boolean[n];
diag1Used = new boolean[2*n-1]; //主对角线 长度为n的方阵, 有(2*n-1)条对角线
diag2Used = new boolean[2*n-1]; //反对角线
char[][] grid = new char[n][n];
for(int i=0; i list = new ArrayList<>();
for(int i=0; i
leetcode 52 N皇后II(困难)
将51号问题中返回的具体解法改为返回解法个数
解法:
class Solution {
private boolean[] rowUsed, colUsed, diag1Used, diag2Used;
private int res = 0;
private int n;
public int totalNQueens(int n) {
this.n = n;
// 同一条主对角线上的位置坐标和i+j相等, 同一条反对角线上的位置坐标差i-j相等,为了保证为正(用作数组下标)需加上(n-1)
// 当尝试在第i行,第j列放置皇后时,需要保证在第i行,第j列, 坐标和为i+j的主对角线,以及坐标差为i-j+n-1的反对角线上不存在皇后
rowUsed = new boolean[n];
colUsed = new boolean[n];
diag1Used = new boolean[2*n-1]; //主对角线 长度为n的方阵, 有(2*n-1)条对角线
diag2Used = new boolean[2*n-1]; //反对角线
char[][] grid = new char[n][n];
for(int i=0; i
leetcode 93 复原ip地址(中等)
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
示例:
输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]
题解:
class Solution {
private ArrayList res = new ArrayList<>();
public List restoreIpAddresses(String s) {
ArrayList ip = new ArrayList<>();
dfs(s, 0, ip);
return res;
}
private void dfs(String s, int index, ArrayList ip){
if(index==s.length() && ip.size() == 4){
res.add(String.join(".", ip));
return;
}
for(int i=1; i<=3; i++){
if((index+i) > s.length()){
break;
}
String next = s.substring(index, index+i);
// 一个合法的ip段要满足范围为[0,255]且值为非零时不可有前导0
if((next.length()>1 && next.charAt(0)!='0' && Integer.valueOf(next)<=255) || next.length() ==1){
// ip多有4个字段
if(ip.size()<4){
ip.add(next);
dfs(s, index+i, ip); // 注意:这里是 index+i
ip.remove(ip.size()-1);
}
}
}
return;
}
}
leetcode 131 分割回文串(中等)
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
题解:
class Solution {
private ArrayList> res = new ArrayList>();
public List> partition(String s) {
int n = s.length();
if(n==0){
return res;
}
LinkedList list = new LinkedList<>();
sub(s, 0, list);
return res;
}
private void sub(String s, int index, LinkedList list){
if(index == s.length()){
res.add(new LinkedList(list));
return;
}
for(int i=1; i<=s.length(); i++){
if(index+i > s.length()){
break;
}
String cur = s.substring(index, index+i);
if(isPalindrome(cur, 0, cur.length()-1)){
list.addLast(cur);
sub(s, index+i, list);
list.removeLast();
}
}
return;
}
private boolean isPalindrome(String s, int l, int r){
while(l
257 二叉树的所有路径(中等)
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
输入:
1
/ \
2 3
\
5
输出: [“1->2->5”, “1->3”]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
题解:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List binaryTreePaths(TreeNode root) {
List l = new ArrayList<>();
if(root == null){
return l;
}
if(root.left == null && root.right == null){
l.add(root.val+"");
return l;
}
List ll = binaryTreePaths(root.left);
for(String e : ll){
l.add(root.val+"->"+e);
}
List rl = binaryTreePaths(root.right);
for(String e : rl){
l.add(root.val+"->"+e);
}
return l;
}
}
题解2:
class Solution {
private ArrayList res = new ArrayList<>();
public List binaryTreePaths(TreeNode root) {
if(root == null){
return res;
}
dfs(root, "");
return res;
}
private void dfs(TreeNode node, String s){
if(node.left == null && node.right == null){
s+=node.val;
res.add(s);
s = s.substring(0, s.length()-1);
return;
}
s = s + node.val;
if(node.left != null){
dfs(node.left, s+"->");
}
if(node.right != null){
dfs(node.right, s+"->");
}
s = s.substring(0, s.length()-1);
return;
}
}