算法·每日一题(详解+多解)-- day14

简介: 算法·每日一题(详解+多解)-- day14

算法·每日一题(详解+多解)-- day14


✨博主介绍

leetcode-47. 全排列 II

题解分析

代码实现:

leetcode-45.跳跃游戏 II

题解分析

代码实现:

leetcode-56. 合并区间

题解分析

代码实现:

leetcode-100. 相同的树

题解分析

代码实现:

💫点击直接资料领取💫


✨博主介绍


💂 个人主页:苏州程序大白


💂 个人社区:CSDN全国各地程序猿


🤟作者介绍:中国DBA联盟(ACDU)成员,CSDN全国各地程序猿(媛)聚集地管理员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室,2021年注册苏州凯捷智能科技有限公司


💅 有任何问题欢迎私信,看到会及时回复


👤 微信号:stbsl6,微信公众号:苏州程序大白


💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)


🎯 想加入技术交流群的可以加我好友,群里会分享学习资料


leetcode-47. 全排列 II


全排列 II


6e2be15b5dcf46e797c0851c8a78d1cd.png


题解分析


定义全局存储最终结果集和临时结果集的变量。定义一个存储布尔值的数组并全部赋值为 false,把传进来的数组排序,排序完传入回溯,得到最终答案后返回最终结果集即可。

 

回溯算法传入的参数有已排序的数组和全是 false 的布尔数组。数组长度和临时结果集的长度进行比较,当临时结果集存储的个数跟传进来的数组的长度相等时说明排序完毕,若排序完毕则加入结果集,记得将临时结果集加入数组中。


若没排序完,则对传入的待排序数组进行判断,若 nums[i] == nums[i - 1] 即当前层选择的数与上一层所选择的一样,且 used[i - 1] == false 即说明同⼀树层 nums[i - 1] 使⽤过则直接跳过,进入下一循环。如果同⼀树⽀ nums[i] 没使⽤过则开始处理,标记同⼀树⽀ nums[i] 使⽤过,防止同一树支重复使用,进入回溯,说明同⼀树层 nums[i] 使⽤过,防止下一树层。


代码实现:


class Solution {
    //定义结果集
    List<List<Integer>> result = new ArrayList<>();
    //定义临时结果集
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        boolean[] used = new boolean[nums.length];
        // 将 used 全部赋值为 false
        Arrays.fill(used, false);
        // 对传进来的数组进行排序
        Arrays.sort(nums);
        // 进入回溯主体
        backTrack(nums, used);
        // 返回最终结果集
        return result;
    }
    // 实现回溯
    private void backTrack(int[] nums, boolean[] used) {
        // 当临时结果集存储的个数跟传进来的数组的长度相等时说明排序完毕
        if (path.size() == nums.length) {
            // 将排序好的结果加入结果集中
            result.add(new ArrayList<>(path));
            return;
        }
        // 开始遍历
        for (int i = 0; i < nums.length; i++) {
            // 如果同⼀树层 nums[i - 1] 使⽤过则直接跳过
            if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
                continue;
            }
            //如果同⼀树⽀ nums[i] 没使⽤过开始处理
            if (used[i] == false) {
                //标记同⼀树⽀ nums[i] 使⽤过,防止同一树支重复使用
                used[i] = true;
                path.add(nums[i]);
                backTrack(nums, used);
                //回溯,说明同⼀树层 nums[i] 使⽤过,防止下一树层重复
                path.remove(path.size() - 1);
                used[i] = false;
            }
        }
    }
}


leetcode-45.跳跃游戏 II


跳跃游戏 II


22e6d5ab84654b05a31fbb0fb9c5ef22.png


题解分析


首先对传进来的数组进行判空,若不为空则继续。分别定义记录跳跃的次数、记录当前的覆盖最大区域和最大的覆盖区域三个变量。对数组进行遍历,求出在可覆盖区域内更新最大的覆盖区域,若最大的覆盖区域大于等于数组最后一个的位置则证明再跳一步就到达了末尾,则只需要走到走到当前覆盖的最大区域,下一步就到末尾,因此到了这一步后步数加一即为所求。


代码实现:


class Solution {
     public int jump(int[] nums) {
        // 对传进来的数组进行判空
        if (nums == null || nums.length == 0 || nums.length == 1) {
            return 0;
        }
        //记录跳跃的次数
        int count = 0;
        //当前的覆盖最大区域
        int curDistance = 0;
        //最大的覆盖区域
        int maxDistance = 0;
        for (int i = 0; i < nums.length; i++) {
            //在可覆盖区域内更新最大的覆盖区域
            maxDistance = Math.max(maxDistance,i + nums[i]);
            //说明当前一步,再跳一步就到达了末尾
            if (maxDistance >= nums.length - 1){
                count++;
                break;
            }
            //走到当前覆盖的最大区域时,更新下一步可达的最大区域
            if (i == curDistance){
                curDistance = maxDistance;
                count++;
            }
        }
        // 返回最终结果
        return count;
    }
}


leetcode-56. 合并区间


合并区间


511eab4dea684014b2363c2df8137294.png


题解分析


合并区间就是将有重叠区间的两个区间合成一个。首选定义一个存放 int 类型数组的集合作为临时结果集,对传进来的二维数组进行判空,若传进来的 intervals 为空,则直接返回,由于结果集是临时的结果集,记得将一维数组的集合 toArray 成题目最终返回要求的二维数组。利用函数式编程,实现 Comparator 接口,对起点进行从小到大排序,跟 foreach 类似。


定义一个循环维护的变量,当 i 的值小于 intervals 中的集合个数时,进入循环,确保能遍历到最后一个区间,每次遍历都取出区间的左右端点,若当前区间的右端点比下一个区间的左端点还大,则说明区间有重叠,将当前右端点的值与下一个区间右端点的值进行比较,取较大的值作为新区间右端点,将新区间放入结果集中并接着判断下一个区间,最后返回最终结果集,将 List 类型转换成 0 行 n 列的格式的数组类型返回即可。


代码实现:


class Solution {
    public int[][] merge(int[][] intervals) {
        // 定义结果集
        List<int[]> res = new ArrayList<>();
        // 若传进来的 intervals 为空,则直接返回,记得 toArray 成题目最终返回要求
        if (intervals.length == 0 || intervals == null){
            return res.toArray(new int[0][]);
        }
        // 这是函数式编程,实现的是 Comparator 接口,对起点进行从小到大排序
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        // 定义一个循环维护的变量
        int i = 0;
        // 当 i 的值小于 intervals 中的集合个数时,进入循环
        while (i < intervals.length) {
            // 每次遍历都取出区间的左右端点
            int left = intervals[i][0];
            int right = intervals[i][1];
            // 若当前区间的右端点比下一个区间的左端点还大,则说明区间有重叠
            while (i < intervals.length - 1 && intervals[i + 1][0] <= right) {
                // 将当前右端点的值与下一个区间右端点的值进行比较,取较大的值作为新区间右端点
                right = Math.max(right, intervals[++i][1]);
            }
            // 将新区间放入结果集中
            res.add(new int[]{left, right});
            // 接着判断下一个区间
            i++;
        }
        // 返回最终结果集,将 List<int[]> 类型转换成 0 行 n 列的格式的数组类型 ,即一维数组转二维数组
        return res.toArray(new int[0][]);
    }
}


leetcode-100. 相同的树


相同的树


2ea2d489f7f34fbbb01a20c1fc0e4e80.png


题解分析


这道题可以采用递归判断的方法。首先对对传进来的的两个节点进行判空,若两个均为空则说明是一样的,但是任一节点一个为空另一个非空的和两节点都有值,但是值不同的均为不同的树了。若两节点有值且相同,则继续往下遍历,对应的左子节点与右子节点均要相同,递归直到结束,若都相同则为相同的树,否则不是相同的树。


代码实现:


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        // 节点都为空则说明是一样的
        if (p == null && q == null) {
            return true;
        // 任一节点一个为空另一个非空,则说明是不同的树了
        } else if (p == null || q == null) {
            return false;
        // 两节点都有值,但是值不同也是不同的树
        } else if (p.val != q.val) {
            return false;
        // 若两节点有值且相同,则继续往下遍历,对应的左子节点与右子节点均要相同,递归直到结束,若都相同则为相同的树,否则不是相同的树
        } else {
            return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
        }
    }
}



相关文章
|
6月前
|
算法
单链表(算法面试题2)---单链表进阶2 一题多解,逐步优化
单链表(算法面试题2)---单链表进阶2 一题多解,逐步优化
28 0
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day11
💖1. 按之字形顺序打印二叉树 💖2. 二叉搜索树的第k个节点 💖3. 二叉搜索树的第k大节点
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day10
💖1. 和为S的连续正数序列 💖2. 左旋转字符串 💖3. 翻转单词序列
108 0
|
算法 测试技术
【迎战蓝桥】 算法·每日一题(详解+多解)-- day9
💖1. 两个链表的第一个公共结点 💖2. 二叉树的深度 💖3. 数组中只出现一次的数字
【迎战蓝桥】 算法·每日一题(详解+多解)-- day9
|
存储 算法 搜索推荐
【迎战蓝桥】 算法·每日一题(详解+多解)-- day8
💖1. 连续子数组的最大和 💖2. 回文数索引 💖3. 把数组排成最小的数
【迎战蓝桥】 算法·每日一题(详解+多解)-- day8
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day5
💖1. 数组中出现次数超过一半的数字 💖2. 二进制中1的个数 💖3. 替换空格
【迎战蓝桥】 算法·每日一题(详解+多解)-- day5
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day3
💖1. 链表中倒数第k个结点 💖2. 反转链表(五种解题思路) 💖3. 合并两个排序的链表
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day2
💖1. 斐波那契数列 💖2. 青蛙跳台阶问题 💖3. 矩形覆盖
|
算法
【迎战蓝桥】 算法·每日一题(详解+多解)-- day1
【迎战蓝桥】 算法·每日一题(详解+多解)-- day1
【迎战蓝桥】 算法·每日一题(详解+多解)-- day1
|
算法 Java 程序员
算法·每日一题(详解+多解)-- day13
算法·每日一题(详解+多解)-- day13
192 0
算法·每日一题(详解+多解)-- day13