Bootstrap

leetcode刷题(51-60)

算法是码农的基本功,也是各个大厂必考察的重点,让我们一起坚持写题吧。

遇事不决,可问春风,春风不语,即是本心。

我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦,慢慢来,会很快,向前走,别回头。

目录

1、N皇后

2、N皇后II

3、最大子数组和

4、螺旋矩阵

5、跳跃游戏

6、合并区间

7、插入区间

8、最后一个单词的长度

9、螺旋矩阵II

10、排列序列


1、N皇后

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/n-queens/description/思路:回溯标记法,用三个集合标记在列、主对角线、副对角线是否出现过,标记数组标记每行皇后所在的列,递归生成N皇后即可。

class Solution {
    public List<List<String>> solveNQueens(int n) {
        // 三个集合,用于标记每一列、主对角线、副对角线有没有放置皇后
        Set<Integer> column = new HashSet<>() ;
        Set<Integer> left = new HashSet<>() ;
        Set<Integer> right = new HashSet<>() ;
        List<List<String>> ans = new ArrayList<>() ;
        // 标记数组,用于标记每一行皇后所在的列
        int [] queues = new int [n] ;
        Arrays.fill(queues, -1) ;
        dfs(0,n,queues,column,left,right,ans) ;
        return ans ;
    }
    public void dfs(int row, int n, int [] queues, Set<Integer> column, Set<Integer> left, Set<Integer> right, List<List<String>> ans){

        if(row == n){
            List<String> list = new ArrayList<>() ;
            list = genList(queues,n) ;
            ans.add(new ArrayList(list)) ;
        }else{
            for(int i=0; i<n; i++){
                if(column.contains(i)){
                    continue ;
                }
                if(left.contains(row-i)){
                    continue ;
                }
                if(right.contains(row+i)){
                    continue ;
                }
                queues[row] = i ;
                column.add(i) ;
                left.add(row - i) ;
                right.add(row + i) ;
                dfs(row+1,n,queues, column, left, right, ans) ;
                queues[row] = -1 ;
                column.remove(i) ;
                left.remove(row - i) ;
                right.remove(row + i) ;
            }
        }
    }
    public List<String> genList(int [] queues, int n){
        List<String> list = new ArrayList<>() ;
        for(int i=0; i<n; i++){
            char [] c = new char [n] ;
            Arrays.fill(c,'.') ;
            c[queues[i]] = 'Q' ;
            String str = new String(c) ;
            list.add(str) ;
        }
        return list ;
    }
}

2、N皇后II

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/n-queens-ii/description/

思路:这题的解题思路和上一题类似,回溯标记法,每次找出一个方案,就累计一次即可。

class Solution {
    public int totalNQueens(int n) {
        Set<Integer> coulumn = new HashSet<>() ;
        Set<Integer> left = new HashSet<>() ;
        Set<Integer> right = new HashSet<>() ;
        return dfs(0,n,coulumn,left,right) ;
    }
    public int dfs(int row, int n, Set<Integer> coulumn, Set<Integer> left, Set<Integer> right){
            if(row == n){
                return 1 ;
            }
            
            int cnt = 0 ;
            for(int i=0; i<n; i++){
                if(coulumn.contains(i)){
                    continue ;
                }
                if(left.contains(row - i)){
                    continue ;
                }
                if(right.contains(row + i)){
                    continue ;
                }
                coulumn.add(i) ;
                left.add(row - i) ;
                right.add(row + i) ;
                cnt += dfs(row + 1, n, coulumn, left, right) ;
                coulumn.remove(i) ;
                left.remove(row - i) ;
                right.remove(row + i) ;
            }
            return cnt ;
        }
}

3、最大子数组和

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/maximum-subarray/

思路:本质上是一种贪心策略,当前累加的和大于0,就继续累加,否则不累加,整个过程中计算最大值即可。

class Solution {
    public int maxSubArray(int[] nums) {
        int max = Integer.MIN_VALUE ;
        int sum = 0 ;
        for(int i=0; i<nums.length; i++){
            sum = (sum >= 0 ? sum + nums[i] : nums[i]) ;
            max = Math.max(max, sum) ;
        }
        return max  ;
    }
}

4、螺旋矩阵

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/spiral-matrix/

思路:top和bottom模拟上下的位置,left和right模拟左右的位置,在while循环里面,使用for循环模拟顺时针打印矩阵元素。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> ans = new ArrayList<>() ;
        // 模拟旋转过程
        int top = 0,  bottom = matrix.length-1, left = 0, right = matrix[0].length-1;
        while(true){
            for(int i=left; i<=right; i++){
                ans.add(matrix[top][i]) ;
            }
            top ++ ;
            if(top > bottom){
                break ;
            }
            for(int i=top; i<=bottom; i++){
                ans.add(matrix[i][right]) ;
            }
            right --;
            if(left > right){
                break ;
            }
            for(int i=right; i>=left; i--){
                ans.add(matrix[bottom][i]) ;
            }
            bottom -- ;
            if(top > bottom){
                break ;
            }
            for(int i=bottom; i>=top; i--){
                ans.add(matrix[i][left]) ;
            }
            left ++ ;
            if(left > right){
                break ;
            }
        }
        return ans ;
    }
  
}

5、跳跃游戏

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/jump-game/description/

思路:从后向前反退,用step进行标记,step初始化为1,不能跳到当前步,则step+1,否则step更新为1,最后step为1,则表示可以由最初位置跳到最后。

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length ;
        if(n==1){
            return true ;
        }
        int step = 1 ;
        for(int i=n-2; i>=0; i--){
            if(nums[i]>=step){
                step = 1 ;
            }else{
                step ++ ;
            }
        }
        return step == 1 ? true : false ;
    }
}

6、合并区间

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/merge-intervals/

思路:首先需要进行排序,区间的最左侧元素进行排序,然后以此对比当前区间的右侧和下一个区间的左侧元素,决定是否进行合并区间。

当前区间右侧元素 < 下一区间左侧元素。无重叠,直接加入集合

反之,合并区间:注意合并区间,是选择右侧元素的最大值。

class Solution {
    public int[][] merge(int[][] intervals) {

        List<int []> list = new ArrayList<>() ;
        Arrays.sort(intervals, new Comparator<>(){
            public int compare(int [] o1, int [] o2){
                return o1[0] - o2[0] ;
            }
        }) ;

        for(int i=0; i<intervals.length; i++){
            int left = intervals[i][0], right = intervals[i][1] ;
            if(list.size() == 0 || list.get(list.size()-1)[1] < left){
                list.add(new int []{left, right}) ;
            }else{
                // 合并区间
                list.get(list.size()-1)[1] = Math.max(list.get(list.size()-1)[1], right) ;
            }
        }
        int [][] res = new int [list.size()][2] ;
        for(int i=0; i<list.size(); i++){
            res[i][0] = list.get(i)[0] ;
            res[i][1] = list.get(i)[1] ;
        }
        return res ;
    }
}

7、插入区间

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/insert-interval/description/

思路:和上面一题的思路一致,唯一的区别就是开辟一个新数组,将两个数组合并到新数组,然后在进行合并合并区间。

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int [][] tmp = new int [intervals.length+1][2] ;
        for(int i=0; i<intervals.length; i++){
            tmp[i][0] = intervals[i][0] ;
            tmp[i][1] = intervals[i][1] ;
        }
        tmp[tmp.length-1][0] = newInterval[0] ;
        tmp[tmp.length-1][1] = newInterval[1] ;
        List<int []> list = new ArrayList<>() ;
        Arrays.sort(tmp, new Comparator<>(){
            public int compare(int [] o1, int [] o2){
                return o1[0] - o2[0] ;
            }
        }) ;
        for(int i=0; i<tmp.length; i++){
            int left = tmp[i][0], right = tmp[i][1] ;
            if(list.size()==0 || list.get(list.size()-1)[1] < left){
                list.add(new int []{left, right}) ;
            }else{
                list.get(list.size()-1)[1] = Math.max(list.get(list.size()-1)[1], right) ;
            }
        }
        int [][] res = new int [list.size()][2] ;
        for(int i=0; i<res.length; i++){
            res[i][0] = list.get(i)[0] ;
            res[i][1] = list.get(i)[1] ;
        }
        return res ;
    }
}

8、最后一个单词的长度

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/length-of-last-word/

思路:先删除前后的空格,然后从后向前判断,不等于空格,计数器加1,等于空格结束。

class Solution {
    public int lengthOfLastWord(String s) {
       int cnt = 0 ;
       s = s.trim() ;
       for(int i=s.length()-1; i>=0; i--){
        if(s.charAt(i) != ' '){
            cnt ++ ;
        }else{
            break ;
        }
       } 
       return cnt ;
    }
}

9、螺旋矩阵II

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/spiral-matrix-ii/description/

思路:和螺旋矩阵I的思路一样,只不是这是新建一个数组进行模拟而已,本质上都是定义上下左右四个边界,模拟顺时针旋转并更新四个边界值。

class Solution {
    public int[][] generateMatrix(int n) {
        int [][] res = new int [n][n] ;
        int left = 0, right = n-1, top = 0, bottom = n-1 ;
        int v = 1 ;
        while(true){
            for(int i=left; i<=right; i++){
                res[top][i] = v ++ ;
            }
            top ++ ;
            if(top>bottom){
                break ;
            }
            for(int i=top; i<=bottom; i++){
                res[i][right] = v ++ ;
            }
            right -- ;
            if(left > right){
                break ;
            }
            for(int i=right; i>=left; i--){
                res[bottom][i] = v ++ ;
            }
            bottom -- ;
            if(top > bottom){
                break ;
            }
            for(int i=bottom; i>=top; i--){
                res[i][left] = v ++ ;
            }
            left ++ ;
            if(left > right){
                break ;
            }
        }
        return res ;
    }
}

10、排列序列

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/permutation-sequence/description/

思路:全排列+根据字符串进行排序即可。

class Solution {
    public String getPermutation(int n, int k) {
        String s = "" ;
        for(int i=1; i<=n; i++){
            s+= i ;
        }
        List<String> list = new ArrayList<>() ;
        boolean [] vis = new boolean[n] ;
        dfs(list,s,n, new StringBuilder(""), vis) ;
        Collections.sort(list) ;
        return list.get(k-1) ;
    }
    public void dfs(List<String> list, String s, int n, StringBuilder sb, boolean [] vis){
        if(sb.length() == n){
            list.add(sb.toString()) ;
        }
        for(int i=0; i<n; i++){
            if(vis[i]){
                continue ;
            }
            vis[i] = true ;
            sb.append(s.charAt(i)) ;
            dfs(list, s, n, sb, vis) ;
            sb.deleteCharAt(sb.length()-1) ;
            vis[i] = false ;
        }
    }
}
;