刷题-递归

全排列-leetcode47

思路:

通过递归,每一层如果发现是相同的参数,则不再向下递归,因为这个位置上相同的数字会造成结果的重复

代码

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> usedIndex = new ArrayList<>();
        permuteUnique(nums, usedIndex, result);
        return result;
        
    }

    public void permuteUnique(int[] nums, List<Integer> usedIndex, List<List<Integer>> result) {
        if (nums.length == usedIndex.size()) {
            List<Integer> list = new ArrayList<>();
            for (Integer index : usedIndex) {
                list.add(nums[index]);
            }
            result.add(list);
            return;
        }

        List<Integer> usedEle = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            if (usedIndex.contains(i) || usedEle.contains(nums[i])) {
                continue;
                
            }
            usedIndex.add(i);
            permuteUnique(nums, usedIndex, result);
            usedIndex.remove(usedIndex.size() - 1);
            usedEle.add(nums[i]);
        }
    }
}

时间复杂度空间复杂度分析

时间复杂度:n*n!

空间复杂度:O(n),递归深度为n,构建结果的时候集合长度为n

组合总数III-leetcode216

思路

       思路一:通过深度搜索,一个数字可以有两个选择,添加到结果中,或者不添加到结果中,可以以大于目标,等于目标,或者加到9为结束的条件。

思路二:以二进制数作为集合的子集,如果某一位是1就表示该数添加到结果中。遍历所有的数字,并选择其中1的位数为k的数字,然后计算结果。时间复杂度为2^9 * k。空间复杂度为常量。

代码

class Solution {
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> re = new ArrayList<>();
        combination(1, k , re, result, n);
        return result;
        
    }

    public void combination(int index, int k, List<Integer> re, List<List<Integer>> result, int target) {
        if (target == 0 && k == re.size()) {
            result.add(new ArrayList<>(re));
            return;
        }
        if (target <= 0 || k <= re.size() || index > 9) {
            return;
        }
        re.add(index);
        combination(index + 1, k, re, result, target - index);
        re.remove(re.size() - 1);
        combination(index + 1, k, re, result, target);
    }
}

复杂度分析

时间复杂度 k * 2 ^ 9

空间复杂度:M(m)

分割回文串 -leetcode131

思路

通过深度优先搜索,每个字符都有分割和不分割两个选择,要分割就需要和之前未分割的组成一个字符串,同时需要判断这个字符串是否符合回文串.不分割则继续往下一个字符。结束条件是字符串不符合回文串的要求或者字符走到最后一个字符。

代码

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> result = new ArrayList<>();
        List<String> re = new ArrayList<>();
        partition(result, re, 0, 1, s);
        return result;


        
    }

    public void partition(List<List<String>> result, List<String> re, int start, int end, String s) {
        if (start + 1 == end && start == s.length()) {
            result.add(new ArrayList<>(re));
            return;
        }

        if (end > s.length()) {
            return;
        }

        if (check(s.substring(start, end))) {
            re.add(s.substring(start, end));
            partition(result, re, end, end + 1, s);
            re.remove(re.size() - 1);
        }

        partition(result, re, start, end + 1, s);
    }

    public boolean check(String s) {
        if (s.length() == 0) {
            return false;
        }
        for (int i = 0; i < s.length() / 2; i++) {
            if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
                return false;
            }
        }
        return true;
    }

    
}

复杂度分析

时间复杂度:O(2 ^len * len)

空间复杂度:O(len)

复原ip地址-leetcode 93

思路:

        分四层递归处理IP

复杂度

时间复杂度:O(4 * s)s是ip地址的长度

空间复杂度:四层的栈空间

电话号码的字母组合 - leetcode17

思路

采用回溯的方式

解数独-leetcode37

代码

class Solution {

    private boolean finish = false;
    public void solveSudoku(char[][] board) {
        solveSudoku(board, 0, 0);

        
    }

     public void solveSudoku(char[][] board, int i, int j) {
        if (finish) {
            return;
        }
        if (i == 9) {
            finish = true;
            return;
        }
        if (board[i][j] != '.') {
            int jIndex = j == 8 ? 0 : j + 1;
            int iIndex = j == 8 ? i + 1 : i;
            solveSudoku(board,iIndex, jIndex);
            return;
        }
        
        for (char k = '1'; k <= '9'; k++) {
            if (check(board, k, i, j)) {
                board[i][j] = k;
                solveSudoku(board, j == 8 ? i + 1 : i, j == 8 ? 0 : j + 1);
                if (finish) {
                    return;
                }
                board[i][j] = '.';
            }
        }


    }

    public boolean check(char[][] board, char num, int iIndex, int jIndex) {
        for (int i = 0; i < board.length; i++) {
            if (num == board[i][jIndex]) {
                return false;
            }
        }

        for (int i = 0; i < board[0].length; i++) {
            if (num == board[iIndex][i]) {
                return false;
            }
        }

        int iLevel = (iIndex / 3) * 3;
        int jLevel = (jIndex / 3) * 3;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[iLevel + i][jLevel + j] == num) {
                    return false;
                }
            }
        }
        return true;
    }
}

思路

递归+回溯:有点儿暴力搜索的意思,但是需要注意有填写数字的位置,往后循环的方式。

复杂度分析

时间复杂度:O(9 ^(9*9))

空间复杂度:(9 * 9)

我觉得还是看面经吧!刷题穿插着来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值