常见面试算法题(回溯算法)

288 阅读4分钟

模版--来源lanbulandong

result = []
def backtrack(路径, 选择列表): 
	if 满足结束条件:
		result.add(路径) return
      
	for 选择 in 选择列表: 	
	做选择
	backtrack(路径, 选择列表) 
  撤销选择

子集问题

1.无重复元素的数组所有子集

leetcode-cn.com/problems/su…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        if(n == 0 )return res;
        List<Integer> list = new ArrayList<>();
        dfs(nums , 0 , list);
        return res;
    }

    void dfs(int[] nums , int start , List<Integer> list){
        res.add(new ArrayList<>(list));

        for(int i = start ; i < nums.length ; i++){
            list.add(nums[i]);
            dfs(nums , i+1 , list);
            list.remove(list.size()-1);
        }
    }
}

2.有重复元素的数组所有子集

leetcode-cn.com/problems/su…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        int n = nums.length;
        if(n == 0) return res;
        Arrays.sort(nums);
        List<Integer> list = new ArrayList<>();
        dfs(nums , 0 , list);
        return res;
    }

    void dfs(int[] nums , int start , List<Integer> list){
        res.add(new ArrayList<>(list));
        for(int i = start ; i < nums.length ; i++){
            if(i > start && nums[i] == nums[i-1] ) continue;
            list.add(nums[i]);
            dfs(nums , i+1 , list);
            list.remove(list.size()-1);
        }
    }
}

全排列问题

1.无重复数字的全排列

leetcode-cn.com/problems/pe…

class Solution {
    List<List<Integer>> res =  new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        if(nums.length == 0) return res;
        List<Integer> list  = new ArrayList<>();
        boolean[] isv = new boolean[nums.length]; //全排列,每个数字只能用一次,用一个布尔数组来确定是否被访问过
        dfs(nums , list , isv);
        return res;
    }

	//由于每次全排列都是从数组开始到数组结尾,所以不需要传入start
    void dfs(int[] nums  ,List<Integer> list , boolean[] isv){
        if(list.size() == nums.length){ //满足结束条件
            res.add(new ArrayList<>(list));
            return;
        }

        for(int i = 0 ; i < nums.length ; i++){
            if(isv[i]) continue;  //如果已经选择了就continue
            list.add(nums[i]);	//做选择
            isv[i] = true;
            dfs(nums , list , isv);
            list.remove(list.size()-1); //撤销
            isv[i] = false;
        }
    }
}

2.有重复数字的全排列

leetcode-cn.com/problems/pe…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<Integer> list = new ArrayList<>();
        int n = nums.length;
        if(n == 0) return res;
        Arrays.sort(nums); //要先排序
        boolean[] isv = new boolean[n];
        dfs(nums , list , isv);
        return res;
    }

    void dfs(int[] nums , List<Integer> list , boolean[] isv){
        if(list.size() == nums.length){
            res.add(new ArrayList<>(list));
            return;
        }

        for(int i = 0 ; i < nums.length ; i++){
            if(i > 0 && nums[i] == nums[i-1] && isv[i-1]) continue; 
            if(isv[i]) continue;
            list.add(nums[i]);
            isv[i] = true;
            dfs(nums , list , isv);
            list.remove(list.size()-1);
            isv[i] = false; 
        }
    }
}

3.二叉树的所有路径列表

leetcode-cn.com/problems/bi…

class Solution {
    List<String> res = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        if(root == null) return res;
        StringBuilder sb = new StringBuilder();
        dfs(root , sb);
        return res;
    }

    void dfs(TreeNode root , StringBuilder sb){
        if(root == null) return;

        int n = sb.length();
        sb.append(root.val);
        sb.append("->");
        //满足条件,撤销 -> 后加入结果集
        if(root.left == null && root.right == null){
            sb.deleteCharAt(sb.length()-1);
            sb.deleteCharAt(sb.length()-1);
            res.add(new String(sb));
        }

        dfs(root.left , sb);
        dfs(root.right , sb);
        sb.delete(n,sb.length()); //撤销选择,将这回合加入的全部删除

    }
}

4.字符串的全排列

leetcode-cn.com/problems/zi…

class Solution {
    public String[] permutation(String s) {
        if(s == null || s.length() == 0) return new String[0];
        List<String> list = new ArrayList<>();
        char[] chars = s.toCharArray();
        int n = chars.length;
        Arrays.sort(chars);
        boolean[] isv = new boolean[n];
        StringBuilder sb = new StringBuilder();
        dfs( sb , chars , isv ,list);
        String[] res = new String[list.size()];
        for(int i = 0 ; i < res.length ; i++){
            res[i] = list.get(i);
        }
        return res;
    }

    void dfs( StringBuilder sb , char[] chars , boolean[] isv , List<String> list){
        if(sb.length() == chars.length){
            list.add(new String(sb));
        }

        for(int i = 0 ; i < chars.length ; i++){
            if(isv[i]) continue;
            if(i > 0 && chars[i] == chars[i-1] && isv[i-1]) continue;
            sb.append(chars[i]);
            isv[i] = true;
            dfs(sb , chars , isv , list);
            sb.deleteCharAt(sb.length()-1);
            isv[i] = false;
        }
    }
}

5.第k个排列

leetcode-cn.com/problems/pe…

class Solution {
    String res = "";
    int count = 1;
    public String getPermutation(int n, int k) {
        int[] nums = new int[n];
        for(int i = 0 ; i < n ; i++) nums[i] = i+1;
        boolean[] isv = new boolean[n];
        dfs(nums , k , "" , isv);
        return res;
    }

    void dfs(int[] nums , int k , String s , boolean[] isv){
        if(res != "") return;
        if(s.length() == nums.length){
            if(count == k) res = s;
            else count++;
        }

        for(int i = 0 ; i < nums.length ; i++){
            if(isv[i]) continue;
            s = s + nums[i];
            isv[i] = true;
            dfs(nums , k , s , isv);
            s = s.substring(0 , s.length()-1);
            isv[i] = false;
        }
    }
}

组合问题

k个数组合

leetcode-cn.com/problems/co…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        List<Integer> list = new ArrayList<>();
        dfs(n , 1 , k , list);
        return res;
    }

    void dfs(int n , int start ,int k , List<Integer> list){
        if(list.size() == k){
            res.add(new ArrayList<>(list));
            return;
        }
			 //如果 n = 7, k = 4,从 55 开始搜索就已经没有意义了,这是因为:即使把 5 选上,后面的数只有 6 和 7,一共就 3 个候选数,凑不出 4 个数的组合
      //例如:n = 6 ,k = 4。
//path.size() == 1 的时候,接下来要选择 33 个数,搜索起点最大是 44,最后一个被选的组合是 [4, 5, 6];
//path.size() == 2 的时候,接下来要选择 22 个数,搜索起点最大是 55,最后一个被选的组合是 [5, 6];
//path.size() == 3 的时候,接下来要选择 11 个数,搜索起点最大是 66,最后一个被选的组合是 [6]

				//搜索起点的上界 + 接下来要选择的元素个数 - 1 = n
        //i <= n - (k - list.size()) + 1 优化
       // i <= n 也可以,就是效率慢一点
        for(int i = start ; i <= n - (k - list.size()) + 1; i++){
            list.add(i);
            dfs(n , i+1 , k , list);
            list.remove(list.size()-1);
        }
    }
}

组合总和

leetcode-cn.com/problems/co…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> combinationSum(int[] nums, int target) {
        int n = nums.length;
        if(n == 0) return res;
        List<Integer> list = new ArrayList<>();
        dfs(nums , 0 , target , list);
        return res;
    }

    void dfs(int[] nums , int start , int target,  List<Integer> list){
        if(target < 0) return;
        if(target == 0){
            res.add(new ArrayList<>(list));
            return;
        }

        for(int i = start ; i < nums.length ; i++){
            list.add(nums[i]);
            dfs(nums, i , target- nums[i] , list); //因为每个数字可以重复选取,所以i不变
            list.remove(list.size()-1);
        }
    }
}

组合总和2

leetcode-cn.com/problems/co…

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] nums, int target) {
        int n = nums.length;
        if(n == 0) return res;
        List<Integer> list = new ArrayList<>();
        Arrays.sort(nums);
        dfs(nums , 0 , target , list );
        return res;
    }

    void dfs(int[] nums , int start , int target , List<Integer> list ){
        if(target < 0) return;
        if(target == 0){
            res.add(new ArrayList<>(list));
            return;
        }

        for(int i = start ; i < nums.length ; i++){
            if(i > start && nums[i] == nums[i-1]) continue;
            list.add(nums[i]);
            dfs(nums , i+1 , target-nums[i] , list );
            list.remove(list.size()-1);
        }
    }
}

N皇后问题

1.返回所有方案

leetcode-cn.com/problems/n-…

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        //1.初始化棋盘,全部填 '.'
        List<char[]> board = new ArrayList<>();
        for(int i = 0 ; i < n ; i++){
            char[] arr = new char[n];
            Arrays.fill(arr , '.');
            board.add(arr);
        }

        dfs(board , 0); //从第0行开始
        return res;
    }

    void dfs(List<char[]> board , int row){
        if(row == board.size()){ //结束条件
            res.add(transform(board));
            return;
        }
        int n = board.size();
        for(int col = 0 ; col < n ; col++){ //遍历每一列
            if(!isValid(board , row ,col)) continue; //如果无效则返回
            board.get(row)[col] = 'Q'; //做选择
            dfs(board , row+1); //下一行决定
            board.get(row)[col] = '.'; //撤销当前选择
        }

    }

    //检查在 row,col 位置放Q是否有冲突
    boolean isValid(List<char[]> board , int row , int col){
        int n = board.size();
        for(int i = 0 ; i < n ;i++){ // 检查列是否有皇后互相冲突
            if(board.get(i)[col] == 'Q') return false;
        }
        for(int i = row-1 , j = col + 1 ; i >= 0 && j < n ; i--,j++){ //检查右上角
            if(board.get(i)[j] == 'Q') return false;
        }
        for(int i = row-1 , j = col - 1 ; i >= 0 && j >= 0 ; i--,j--){ //检查左上方
            if(board.get(i)[j] == 'Q') return false;
        }
        return true;
    }


    //格式转换函数
    List<String> transform(List<char[]> board){
        List<String> newBoard = new ArrayList<>();
        for(char[] row : board) newBoard.add(new String(row));
        return newBoard;
    }
}

2.返回方案的种类数

leetcode-cn.com/problems/n-…

class Solution {
    int res = 0;
    public int totalNQueens(int n) {
        List<char[]> board = new ArrayList<>();
        for(int i = 0 ; i < n  ;i++){
            char[] arr = new char[n];
            Arrays.fill(arr , '.');
            board.add(arr);
        }
        dfs(board , 0);
        return res;
    }

    void dfs(List<char[]> board , int row){
        if(row == board.size()) res++;

        int n = board.size();
        for(int col = 0 ; col < n; col++){
            if(!isValid(board , row , col)) continue;
            board.get(row)[col] = 'Q';
            dfs(board , row + 1);
            board.get(row)[col] = '.';
        }
    }

    boolean isValid(List<char[]> board , int row  ,int col){
        int n = board.size();
        for(int i = 0 ; i < n ; i++){
            if(board.get(i)[col] == 'Q') return false;
        }

        for(int i = row-1 , j = col+1 ;  i >= 0 && j < n ; i--,j++){
            if(board.get(i)[j] == 'Q') return false;
        }

        for(int i = row-1 , j = col-1 ;  i >= 0 && j >=0 ; i--,j--){
            if(board.get(i)[j] == 'Q') return false;
        }
        return true;
    }
}

数独问题

1.判断是不是有效的数独

leetcode-cn.com/problems/va…

class Solution {
    public boolean isValidSudoku(char[][] board) {
        for(int i = 0 ; i < board.length ; i++){
            for(int j = 0 ; j < board.length ; j++){
                if(board[i][j] == '.') continue;
                if(!isValid(board , i , j)) return false;
            }
        }
        return true;
    }

    private boolean isValid(char[][] board, int row, int col) {
        char c = board[row][col];
        for(int i = 0 ; i < 9 ; i++){
            if(board[i][col] == c && i != row)  return false; //排除自身的情况
            if(board[row][i] == c && i != col)  return false; 
            if(board[3 * (row/3) +i/3][ 3 *(col/3) + i%3] == c 
               && 3 * (row/3) +i/3 != row 
               && 3 *(col/3) + i%3 != col) return false;
        }
        return true;
    }
}

2.解数独

leetcode-cn.com/problems/su…

class Solution {
    public void solveSudoku(char[][] board) {
        backTrace(board , 0 , 0);
    }

    //注意这里的参数,row表示第几行,col表示第几列。
    private boolean backTrace(char[][] board, int row, int col) {
        //注意row是从0开始的,当row等于board.length的时候表示数独的
        //最后一行全部读遍历完了,说明数独中的值是有效的,直接返回true
        if (row == board.length)
            return true;
        //如果当前行的最后一列也遍历完了,就从下一行的第一列开始。这里的遍历
        //顺序是从第1行的第1列一直到最后一列,然后第二行的第一列一直到最后
        //一列,然后第三行的……
        if (col == board.length)
            return backTrace(board, row + 1, 0);
        //如果当前位置已经有数字了,就不能再填了,直接到这一行的下一列
        if (board[row][col] != '.')
            return backTrace(board, row, col + 1);
        //如果上面条件都不满足,我们就从1到9种选择一个合适的数字填入到数独中
        for (char i = '1'; i <= '9'; i++) {
            //判断当前位置[row,col]是否可以放数字i,如果不能放再判断下
            //一个能不能放,直到找到能放的为止,如果从1-9都不能放,就会下面
            //直接return false
            if (!isValid(board, row, col, i))
                continue;
            //如果能放数字i,就把数字i放进去
            board[row][col] = i;
            //如果成功就直接返回,不需要再尝试了
            if (backTrace(board, row, col))
                return true;
            //否则就撤销重新选择
            board[row][col] = '.';
        }
        //如果当前位置[row,col]不能放任何数字,直接返回false
        return false;
    }

    //验证当前位置[row,col]是否可以存放字符c
    private static boolean isValid(char[][] board, int row, int col, char c) {
        for (int i = 0; i < 9; i++) {
            //当前列有没有和字符c重复的
            if (board[i][col] == c)
                return false;
            //当前行有没有和字符c重复的
            if (board[row][i] == c)
                return false;
            //当前的单元格内是否有和字符c重复的
            if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c)
                return false;
        }
        return true;
    }
}

括号生成问题

1. 生成所有的括号组合

leetcode-cn.com/problems/ge…

class Solution {
    List<String> res = new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        if(n == 0) return res;
        String s = "";
        dfs(n , n ,s); //左括号和右括号都为n
        return res;
    }

    void dfs(int l , int r , String s){
        if(l == 0 && r == 0){
            res.add(new String(s));
            return;
        }

        if(l > 0) dfs(l-1 , r , s+"("); //如果左括号大于0,拼接左括号
        if(r > l) dfs(l , r-1 , s+")"); //如果右括号大于左括号个数,拼接右括号
    }
}

矩阵搜索问题(岛屿问题)

1.单词搜索

leetcode-cn.com/problems/wo…

class Solution {
    public boolean exist(char[][] board, String word) {
        int row = board.length;
        if(row == 0) return false;
        int col = board[0].length;
        boolean[][] isv = new boolean[row][col];
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                if(board[i][j] == word.charAt(0) && dfs(board , 0 , i , j , word , isv)) return true;
            }
        }
        return false;
    }

    boolean dfs(char[][] board , int index , int i , int j , String word , boolean[][] isv){
        if(index == word.length()) return true;
        if(i >= board.length || i < 0 || j >= board[0].length || j < 0) return false;
        if(isv[i][j] || word.charAt(index) != board[i][j]) return false;
        isv[i][j] = true;

        if(dfs(board , index+1 , i+1 , j ,word , isv)
          || dfs(board , index+1 , i-1 , j , word , isv)
          || dfs(board , index+1 , i , j+1 , word , isv)
          || dfs(board , index+1 , i , j-1 ,word , isv)) return true;

        isv[i][j] = false;
        return false;
    }
}

2.岛屿数量

leetcode-cn.com/problems/nu…

class Solution {
    public int numIslands(char[][] grid) {
        int row = grid.length;
        if(row == 0) return 0;
        int col = grid[0].length;
        int res = 0;
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                if(grid[i][j] == '1'){
                    dfs(i , j , grid);
                    res++;
                }
            }
        }
        return res;
    }

    void dfs(int i , int j , char[][] grid){
        if(i < 0  || i >= grid.length || j < 0 || j >= grid[0].length) return;
        if(grid[i][j] != '1') return;
        grid[i][j] = '0'; //将相邻的 1 全部变成0
        dfs(i+1 , j , grid);
        dfs(i-1 , j  , grid);
        dfs(i , j+1 , grid);
        dfs(i , j-1 , grid); 
    }
}

3.岛屿的最大面积

leetcode-cn.com/problems/ma…

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int row = grid.length;
        if(row == 0) return 0;
        int col = grid[0].length;
        int res = 0;
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                if(grid[i][j] == 1){
                    res = Math.max(res , dfs(grid , i , j));
                }
            }
        }
        return res;
    }

    int dfs(int[][] grid , int i , int j){
        if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length) return 0;
        if(grid[i][j] != 1) return 0;
        
        int count = 1;
        grid[i][j] = 2;
        count += dfs(grid , i+1 , j);
        count += dfs(grid , i , j+1);
        count += dfs(grid , i-1 , j);
        count += dfs(grid , i , j-1);
        return count;
    }
}

4. 统计封闭岛屿的数目

(leetcode-cn.com/problems/nu…)

class Solution {
    // 0 表示陆地
    // 1 表示水域
    // 2 表示已经计算过了
    public int closedIsland(int[][] grid) {
        int res = 0;
        for(int i = 0 ;i < grid.length ; i++){
            for(int j = 0 ; j < grid[0].length ;j++){
                if(grid[i][j] == 0){
                    if(dfs(i ,j ,grid)) // 如果是封闭岛屿
                    res++;
                }
            }
        }
        return res;
    }

    //判断是不是封闭岛屿
    boolean dfs(int i , int j ,int[][] grid){
        //封闭岛屿
        if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length ) return false;
        if(grid[i][j] != 0) return true;
         grid[i][j]   = 2;
        boolean down  = dfs(i+1,j,grid);
        boolean up    = dfs(i-1,j,grid);
        boolean left  = dfs(i,j+1,grid);
        boolean right = dfs(i,j-1,grid);
        if(up && down && left && right){
            return true;
        }
        return false;
    }
}

5.统计岛屿的周长

leetcode-cn.com/problems/is…

class Solution {
    public int islandPerimeter(int[][] grid) {
        int row = grid.length;
        if(row == 0) return 0;
        int col = grid[0].length;
        int res = 0;
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                if(grid[i][j] == 1) {
                    res += 4;
                    if(i > 0 && grid[i-1][j] == 1) res -= 2;
                    if(j > 0 && grid[i][j-1] == 1) res -= 2;
                }
                
            }
        }
        return res;
    }
}

其他经典问题

1. 电话号码的字母组合

leetcode-cn.com/problems/le…

class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> res = new ArrayList<>();
        if(digits.length() == 0) return res;
        Map<Character , char[]> map = new HashMap<>();
        map.put('2' , new char[]{'a' , 'b' ,'c'});
        map.put('3' , new char[]{'d' , 'e' ,'f'});
        map.put('4' , new char[]{'g' , 'h' ,'i'});
        map.put('5' , new char[]{'j' , 'k' ,'l'});
        map.put('6' , new char[]{'m' , 'n' ,'o'});
        map.put('7' , new char[]{'p' , 'q' ,'r','s'});
        map.put('8' , new char[]{'t' , 'u' ,'v'});
        map.put('9' , new char[]{'w' , 'x' ,'y','z'});
        StringBuilder sb = new StringBuilder();
        dfs(digits , 0, sb , res , map);
        return res;
    }

    void dfs(String digits ,int start ,StringBuilder sb , List<String> res ,Map<Character , char[]> map){
        //递归终止条件
        if(start == digits.length()){
            res.add(new String(sb));
            return;
        }

        char[] chars = map.get(digits.charAt(start));
        for(int i = 0 ; i < chars.length ; i++){
            sb.append(chars[i]);
            dfs(digits , start+1 , sb , res , map);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}

2. 分割回文串

leetcode-cn.com/problems/pa…

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> partition(String s) {
        int n = s.length();
        List<String> list = new ArrayList<>();
        dfs(s , 0 , list);
        return res;
    }

    void dfs(String s , int start , List<String> list){
        if (start == s.length()){
            res.add(new ArrayList<>(list));
            return;
        }

        for(int i = start ; i < s.length() ; i++){
            String str = s.substring(start , i+1);
            if(isHuiWen(str)){
                list.add(str);
                dfs(s , i+1 , list);
                list.remove(list.size()-1);
            }
        }
    }

    boolean isHuiWen(String s){
        int n = s.length();
        if(n == 1) return true;
        int l = 0 , r = n-1;
        while(l < r){
            if(s.charAt(l) != s.charAt(r)) return false;
            l++;
            r--;
        }
        return true;
    }
}

3. 判断是不是累加数

leetcode-cn.com/problems/ad…

class Solution {
    public boolean isAdditiveNumber(String num) {
        int n = num.length();
        if(n < 3) return false;
        List<Long> list = new ArrayList<>();
        return dfs(num , 0 ,list);
    }
		//int 可能会超数据范围,所以用long
    boolean dfs(String num , int start , List<Long> list){
        if(start == num.length() && list.size() > 2) return true;

        for(int i = start ; i < num.length() ; i++){
            String tem = num.substring(start , i+1);
            if(tem.charAt(0) == '0' && tem.length() > 1) return false; //剪枝:不以0开头
            if(tem.length() > num.length()/2) return false; //剪枝
            int size = list.size();
            if(size < 2 || Long.parseLong(tem) == list.get(size-1) + list.get(size-2)){
                list.add(Long.parseLong(tem));
                if(dfs(num , i+1 , list)) return true;
                list.remove(list.size()-1);
            }
        }
        return false;
    }
}

4. 恢复IP地址

leetcode-cn.com/problems/re…

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        int n = s.length();
        if(n == 0) return res;
        List<String> segment = new ArrayList<>();
        dfs(s , 0 ,segment, res);
        return res;
    }

    void dfs(String s , int start  , List<String> segment , List<String> res){
        if(start == s.length()){
            if(segment.size() == 4){
                StringBuilder sb = new StringBuilder();
                for(String tem : segment) sb.append(tem + ".");
                sb.deleteCharAt(sb.length()-1);
                res.add(new String(sb));
            }
        }

        if(segment.size() > 4) return; //剪枝,大于4个分段就直接返回

        for(int i = start ; i < s.length() && i < start+3 ; i++){
            String tem = s.substring(start , i+1);
            if(tem.charAt(0) == '0' && tem.length() > 1) continue;
            int num = Integer.parseInt(tem);
            if(num <= 255 && num >= 0){
                segment.add(tem);
                dfs(s,i+1,segment ,res);
                segment.remove(segment.size()-1);
            }
        }
    }
}