十日百题04

040.括号生成【中】

22. 括号生成 - 力扣(LeetCode)

题意: 生成给定数目的括号

分析: 括号的数目确定

解法:

class Solution {
    List<String> ans = new ArrayList<>();

    public List<String> generateParenthesis(int n) {
        _generate(n, n, n, "");
        return ans;
    }

    private void _generate(int left, int right, int n, String s) {
        if (left == 0 && right == 0) {
            ans.add(s);
            return;
        }
        if (left > 0) {
            _generate(left - 1, right, n, s + "(");
        }
        if (left < right) {
            _generate(left, right - 1, n, s + ")");
        }
    }
}

041.存在重复元素【简】

217. 存在重复元素 - 力扣(LeetCode)

题意: 判断数组中是否存在重复元素

分析: 可以一开始就给数组进行排序,时间复杂度为 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))

也可以使用hash表,直接看看是否重复即可。

解法: hash O ( n ) O(n) O(n)

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set set = new HashSet();
        for(int i=0;i<nums.length;i++){
            if(!set.add(nums[i])){
                return true;
            }
        }
        return false;
    }
}

042.最大子数组和【中】

53. 最大子数组和 - 力扣(LeetCode)

题意: 寻找数组中连续的和最大的子数组

分析: 如果前面和小于0,那么就不加入前面的

解题: O ( n ) O(n) O(n)

class Solution {
    public int maxSubArray(int[] nums) {
        int ans = nums[0],tmp = 0;
        for(int i = 0; i<nums.length; i++){
            if(tmp>0){
                tmp += nums[i];
            }else{
                tmp=nums[i];
            } 
            if(tmp>ans)ans=tmp;
        }
        return ans;
    }
}

043.验证二叉搜索树【中】

98. 验证二叉搜索树 - 力扣(LeetCode)

题意: 判断是否为二叉搜索树

分析: 要注意左子树始终小于右子树

解法: 递归

class Solution {
    public boolean isValidBST(TreeNode root) {
        return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    public boolean validate(TreeNode node, long min, long max) {
        if (node == null) {
            return true;
        }
        if (node.val <= min || node.val >= max) {
            return false;
        }
        return validate(node.left, min, node.val) && validate(node.right, node.val, max);
    }
}

044.pow(x,n) 【中】🎈

50. Pow(x, n) - 力扣(LeetCode)

题意: 计算x的n次方

分析: 分治计算一半,另一半也就求出来了

解法: 分治 O ( l o g n ) O(logn) O(logn)

class Solution {
    public double getPow(double x,long n) {
        if (n == 0)
            return 1.0;
        double ans = getPow(x, n / 2);
        if (n % 2 == 1)
            return ans * ans * x;
        return ans * ans;
    }
    public double myPow(double x, int n) {
        long N =n;
        return N>=0?getPow(x,N):1.0/getPow(x,-N);
    }
}

045.子集【中】💡

78. 子集 - 力扣(LeetCode)

题意: 寻找一个数组的所有子集

分析: 递归,可以加也可以不加,得到所有情况。

解法①: 递归dfs O ( n ∗ 2 n ) O(n*2^n) O(n2n)

​ 可以加也可以不加,得到所有情况

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        dfs(ans, new ArrayList<Integer>(), nums, 0);
        return ans;
    }
    private void dfs(List<List<Integer>> ans, List<Integer> list, int[] nums, int index) {
        if (index == nums.length) {
            ans.add(new ArrayList<>(list));
            return;
        }
        dfs(ans, list, nums, index + 1);
        list.add(nums[index]);
        dfs(ans, list, nums, index + 1);
        list.remove(list.size() - 1);
    }
}

解法②: 迭代 O ( n ∗ 2 n ) O(n*2^n) O(n2n)

每向后移动,遍历一下所有的结果集,得到加入此数字后集合的值。

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        ans.add(new ArrayList<>());
        for (int num : nums) {
            int n = ans.size();
            for (int i = 0; i < n; i++) {
                List<Integer> tmp = new ArrayList<>(ans.get(i));
                tmp.add(num);
                ans.add(tmp);
            }
        }
        return ans;
    }
}

046.多数元素【简】🎈

169. 多数元素 - 力扣(LeetCode)

题意: 寻找数组中占据一半以上的元素

分析: 如何确定最多的元素?

解法①: 摩尔投票法 O ( n ) O(n) O(n)

多数元素与其它元素一比一消耗,剩下的就是多数元素

class Solution {
    public int majorityElement(int[] nums) {
        int ans = nums[0], count = 1;
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) {
                ans = nums[i];
                count++;
            } else {
                count = (ans == nums[i]) ? count + 1 : count - 1;
            }
        }
        return ans;
    }
}

047.电话号码的字母组合【中】

17. 电话号码的字母组合 - 力扣(LeetCode)

题意: 9键打字,输入数字,输出可能的字母组合

分析: 几层递归即可

解法:

class Solution {
    public List<String> letterCombinations(String digits) {
        if (digits == null || digits.length() == 0)
            return new ArrayList<>();
        Map<Character, String> map = new HashMap<>();
        map.put('2', "abc");
        map.put('3', "def");
        map.put('4', "ghi");
        map.put('5', "jkl");
        map.put('6', "mno");
        map.put('7', "pqrs");
        map.put('8', "tuv");
        map.put('9', "wxyz");
        List<String> list = new LinkedList<>();
        getStr("", 0, list, digits, map);
        return list;
    }

    private void getStr(String str, int i, List<String> list, String digits, Map<Character, String> map) {
        if (i == digits.length()) {
            list.add(str);
            return;
        }
        String letter = map.get(digits.charAt(i));
        for (int j = 0; j < letter.length(); j++) {
            getStr(str + letter.charAt(j), i + 1, list, digits, map);
        }
    }
}

048.n皇后【难】🚩

51. N 皇后 - 力扣(LeetCode)

题意: n皇后

分析: 不能横竖斜

解题: 回溯 O ( n ! ) O(n!) O(n!)

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> solutions = new ArrayList<>();
        int[] queens = new int[n];
        Arrays.fill(queens, -1);
        Set<Integer> columns = new HashSet<>();
        Set<Integer> xie1 = new HashSet<>();
        Set<Integer> xie2 = new HashSet<>();
        getQueen(solutions, queens, n, 0, columns, xie1, xie2);
        return solutions;
    }

    private void getQueen(List<List<String>> solutions, int[] queens, int n, int row, Set<Integer> columns,
            Set<Integer> xie1, Set<Integer> xie2) {
        if (row == n) {
            List<String> board = generateBoard(queens, n);
            solutions.add(board);
        } else {
            for (int i = 0; i < n; i++) {
                if (columns.contains(i)) {
                    continue;
                }
                if (xie1.contains(row - i))
                    continue;
                if (xie2.contains(row + i))
                    continue;
                queens[row] = i;
                columns.add(i);
                xie1.add(row - i);
                xie2.add(row + i);
                getQueen(solutions, queens, n, row + 1, columns, xie1, xie2);
                queens[row] = -1;
                columns.remove(i);
                xie1.remove(row - i);
                xie2.remove(row + i);
            }
        }
    }

    private List<String> generateBoard(int[] queens, int n) {
        List<String> board = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char[] row = new char[n];
            Arrays.fill(row, '.');
            row[queens[i]] = 'Q';
            board.add(new String(row));
        }
        return board;
    }
}

049.二叉树的层序遍历【中】

102. 二叉树的层序遍历 - 力扣(LeetCode)

分析: 层序输出二叉树,相同层次要放到一个数组中

​ 只是简单的层序遍历,不同层次的遍历有两种处理方法,一是新建queue,然后遍历,一是记录queue的size,然后遍历

解法: BFS O ( n ) O(n) O(n)

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new ArrayDeque<>();
        Queue<TreeNode> tmp = new ArrayDeque<>();
        if (root == null)
            return new ArrayList<>();
        queue.add(root);
        List<List<Integer>> ans = new ArrayList<>();
        while (!queue.isEmpty()) {
            tmp = queue;
            queue = new ArrayDeque<>();
            List<Integer> list = new ArrayList<>();
            while (!tmp.isEmpty()) {
                TreeNode node = tmp.poll();
                list.add(node.val);
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            ans.add(list);
        }
        return ans;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值