怒刷LeetCode的第23天(Java版)

news2024/11/19 19:35:50

目录

第一题

题目来源

题目内容

解决方法

方法一:贪心算法

方法二:动态规划

方法三:回溯算法

方法四:并查集

第二题

题目来源

题目内容

解决方法

方法一:排序和遍历

方法二:扫描线算法

方法三:栈

第三题

题目来源

题目内容

解决方法

方法一:遍历和比较


第一题

题目来源

55. 跳跃游戏 - 力扣(LeetCode)

题目内容

解决方法

方法一:贪心算法

这个算法使用贪心的思想,通过遍历数组中的每个元素,始终保持一个能够跳到的最远位置 maxPos。在遍历过程中,如果当前位置超过了 maxPos,则说明无法继续跳跃,返回 false。否则,更新 maxPos 的值,将其与 i + nums[i] 比较,取较大值作为新的 maxPos。最后判断 maxPos 是否已经超过或等于最后一个下标,如果是,则返回 true,否则返回 false。

class Solution {
public boolean canJump(int[] nums) {
    int n = nums.length;
    int maxPos = 0; // 当前能够跳到的最远位置

    for (int i = 0; i < n; i++) {
        if (i > maxPos) {
            // 如果当前位置超过了能够跳到的最远位置,说明无法继续跳跃,返回false
            return false;
        }
        maxPos = Math.max(maxPos, i + nums[i]);
        // 更新能够跳到的最远位置
        if (maxPos >= n - 1) {
            // 如果能够跳到的最远位置已经超过或等于最后一个下标,说明可以到达最后一个下标,返回true
            return true;
        }
    }

    return false;
}

}

复杂度分析:

  • 时间复杂度为 O(n),其中 n 是数组的长度。因为我们只需遍历一次数组即可判断能否到达最后一个下标。
  • 空间复杂度为 O(1),我们只需要保存一个额外的变量 maxPos。

LeetCode运行结果:

方法二:动态规划

除了贪心之外,还可以使用动态规划来解决这个问题。

该算法使用动态规划的思想,定义一个布尔型数组 dp,其中 dp[i] 表示能否从第0个位置跳到第i个位置。

为了计算 dp[i],我们从前往后遍历数组中的每个位置 i,并在其中再次遍历所有位置 j < i。只有当某个位置 j 可以到达,并且从 j 位置可以到达 i 位置时,才有可能到达 i 位置。因此,如果存在一个位置 j 满足条件,即 dp[j] && j + nums[j] >= i,则说明当前位置 i 可以到达,我们将 dp[i] 设置为 true。最终返回 dp[n-1] ,表示能否从第 0 个位置跳到最后一个位置。

class Solution {
public boolean canJump(int[] nums) {
    int n = nums.length;
    boolean[] dp = new boolean[n]; // dp[i] 表示能否从第0个位置跳到第i个位置

    dp[0] = true; // 第0个位置一定可以到达

    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (dp[j] && j + nums[j] >= i) {
                // 如果前面某一个位置可以到达,并且这个位置可以到达i,那么说明i也可以到达
                dp[i] = true;
                break;
            }
        }
    }

    return dp[n - 1];
}
}

复杂度分析:

  • 时间复杂度为 O(n^2),因为在计算 dp[i] 时,需要遍历之前的所有位置 j,所以总共需要进行 n * (n-1) / 2 次比较。
  • 空间复杂度方面,动态规划算法使用了一个长度为 n 的数组 dp,所以空间复杂度为 O(n)。

与贪心算法相比,动态规划算法的时间复杂度较高,但是更加直观易懂,且可以解决更一般化的跳跃游戏问题。

LeetCode运行结果:

方法三:回溯算法

除了贪心算法和动态规划算法,还可以使用回溯算法来解决跳跃游戏问题。

该算法使用回溯的思想,在每个位置上探索所有可能的跳跃,直到找到能到达最后一个位置的路径,或者发现无法到达的情况。

具体实现中,我们定义一个辅助函数 backtrack,其中 position 参数表示当前所在的位置。首先,在每个位置上计算能够跳跃到的最远位置 furthestJump,然后从最远位置开始反向遍历,尝试从当前位置跳到下一个位置 nextPosition,并递归调用 backtrack 函数。如果最终找到一条路径能够到达最后一个位置,则返回 true;如果所有尝试都失败,则返回 false。

class Solution {
public boolean canJump(int[] nums) {
    return backtrack(nums, 0);
}

private boolean backtrack(int[] nums, int position) {
    // 到达最后一个位置,返回 true
    if (position == nums.length - 1) {
        return true;
    }

    int furthestJump = Math.min(position + nums[position], nums.length - 1);
    for (int nextPosition = furthestJump; nextPosition > position; nextPosition--) {
        if (backtrack(nums, nextPosition)) {
            return true;
        }
    }

    return false;
}

}

复杂度分析:

回溯算法的时间复杂度是指数级的,因为在每个位置上都会进行多次递归调用。具体来说,在最坏情况下,即每次跳跃只能跳一个格子,需要进行 n 层递归调用,每层调用需要遍历 nums 数组中的所有元素,因此总时间复杂度是 O(n^n)。

空间复杂度主要取决于递归调用栈的深度,最坏情况下,递归调用栈的深度为数组的长度,所以空间复杂度为 O(n)。

尽管回溯算法能够找到所有可能的路径,但由于其指数级的时间复杂度,对于较大的输入可能会导致超时。因此,在实际应用中,贪心算法和动态规划算法更常用和高效。

LeetCode运行结果:

方法四:并查集

除了贪心算法、动态规划、回溯算法,还可以使用特殊的数据结构来解决跳跃游戏问题,例如并查集。

并查集是一种用于处理元素分组和查找连通性的数据结构。在跳跃游戏问题中,我们可以将每个位置看作一个节点,并按照能够跳跃到的下一个位置建立连通关系。

在实现中,我们首先定义了一个并查集类 UnionFind,其中包含 find、union 和 isConnected 等操作。在构造函数中,将每个位置初始化为其自身的根节点。

接下来,遍历数组 nums 中的每个位置,并计算出从当前位置能够跳跃到的最远位置 maxJump。然后,将当前位置与从 i+1 到 maxJump 的位置进行合并操作,表示它们之间存在连通关系。

最后,判断起点位置 0 和终点位置 n-1 是否连通,即可得出是否能够跳跃到终点位置。

class Solution {
class UnionFind {
    int[] parent;

    public UnionFind(int n) {
        parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }

    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    public void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            parent[rootX] = rootY;
        }
    }

    public boolean isConnected(int x, int y) {
        return find(x) == find(y);
    }
}

public boolean canJump(int[] nums) {
    if (nums == null || nums.length == 0) {
        return false;
    }

    int n = nums.length;
    UnionFind uf = new UnionFind(n);

    for (int i = 0; i < n; i++) {
        int maxJump = Math.min(i + nums[i], n - 1);
        for (int j = i + 1; j <= maxJump; j++) {
            uf.union(i, j);
        }
    }

    return uf.isConnected(0, n - 1);
}

}

复杂度分析:

  • 时间复杂度:O(n^2),其中 n 是数组的长度。需要进行两层循环,对每个位置都进行合并操作。
  • 空间复杂度:O(n),需要使用一个并查集来保存每个位置的根节点。

需要注意的是,并查集不适用于所有类型的跳跃游戏问题,只适用于某些特定情况下。在一般情况下,仍然推荐使用贪心算法、动态规划或回溯算法来解决跳跃游戏问题。

LeetCode运行结果:

第二题

题目来源

56. 合并区间 - 力扣(LeetCode)

题目内容

解决方法

方法一:排序和遍历

这个问题可以使用排序和遍历的思路来解决。

  1. 首先,我们对给定的区间集合按照起始位置进行排序。这样可以确保如果有重叠的区间,它们会相邻。
  2. 然后,我们遍历排序后的区间集合,并维护一个当前合并区间的起始位置 start 和结束位置 end。初始时,我们将第一个区间的起始位置和结束位置分别赋值给 start 和 end。
  3. 接下来,我们从第二个区间开始遍历,比较当前区间的起始位置与当前合并区间的结束位置。如果当前区间的起始位置大于当前合并区间的结束位置,说明当前区间与前面的区间没有重叠,我们可以将当前合并区间 [start, end] 加入结果数组中,并更新 start 和 end 为当前区间的起始位置和结束位置。
  4. 否则,如果当前区间的起始位置小于等于当前合并区间的结束位置,说明当前区间与前面的区间有重叠,我们可以更新当前合并区间的结束位置为当前区间的结束位置。这样就实现了区间的合并。
  5. 最后,遍历完成后,将当前合并区间 [start, end] 加入结果数组中即可。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length <= 1) {
            return intervals;
        }
        
        // 按照区间的起始位置进行排序
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        
        List<int[]> merged = new ArrayList<>();
        int start = intervals[0][0];
        int end = intervals[0][1];
        
        for (int i = 1; i < intervals.length; i++) {
            int intervalStart = intervals[i][0];
            int intervalEnd = intervals[i][1];
            
            if (intervalStart <= end) {
                // 当前区间和前面的区间有重叠,更新当前合并区间的结束位置
                end = Math.max(end, intervalEnd);
            } else {
                // 当前区间和前面的区间没有重叠,将当前合并区间加入结果数组中
                merged.add(new int[]{start, end});
                // 更新当前合并区间为当前区间
                start = intervalStart;
                end = intervalEnd;
            }
        }
        
        // 将最后一个合并区间加入结果数组中
        merged.add(new int[]{start, end});
        
        return merged.toArray(new int[merged.size()][]);
    }
}

复杂度分析:

  • 排序的时间复杂度为O(n log n),其中 n 是区间的数量。这是因为我们对区间进行了一次排序操作。接下来,我们遍历排序后的区间集合,每个区间只会被访问一次。因此,遍历的时间复杂度是O(n),其中 n 是区间的数量。最后,将合并后的区间转换为结果数组的过程需要O(n)的时间复杂度,其中 n 是合并后的区间数量。综上所述,算法的总时间复杂度为O(n log n) + O(n) + O(n) = O(n log n)。
  • 对于空间复杂度,我们使用了一个结果集合来存储合并后的区间,其大小最多为n。因此,空间复杂度为O(n)。

注意,这里不考虑返回结果的空间复杂度。如果按照题目要求返回二维数组作为结果,该空间复杂度为O(n)。

LeetCode运行结果:

方法二:扫描线算法

除了排序和遍历的方法,还可以使用扫描线算法来合并区间。这种方法在处理区间重叠的问题时也很高效。

  1. 首先,我们将所有区间的起始点和结束点提取出来,并分别存储在两个数组中。对于每个点,我们还需要记录它是一个起始点还是结束点。
  2. 然后,我们对这些点进行排序,并使用一个变量 count 来记录当前遍历到的起始点的个数。同时,我们还需要用一个变量 start 来记录当前合并区间的起始位置。
  3. 接着,我们从左到右遍历这些点,并根据每个点的类型来更新 count 的值。当遇到起始点时,说明有一个新的区间开始了,因此 count 加1。当遇到结束点时,说明一个区间结束了,因此 count 减1。
  4. 在遍历过程中,每当 count 的值从0变为1时,说明一个新的合并区间开始了,我们将当前点的位置赋值给 start。每当 count 的值从1变为0时,说明一个合并区间结束了,我们将当前点的位置作为这个区间的结束位置,并将合并区间 [start, end] 加入结果数组中。
  5. 最后,我们就可以得到合并后的区间。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length <= 1) {
            return intervals;
        }
        
        int n = intervals.length;
        
        // 提取所有点的值和类型
        int[] points = new int[2 * n];
        int[] types = new int[2 * n];
        
        for (int i = 0; i < n; i++) {
            points[2 * i] = intervals[i][0];
            types[2 * i] = 1; // 起始点
            points[2 * i + 1] = intervals[i][1];
            types[2 * i + 1] = -1; // 结束点
        }
        
        // 对点进行排序
        Integer[] indices = new Integer[2 * n];
        for (int i = 0; i < 2 * n; i++) {
            indices[i] = i;
        }
        Arrays.sort(indices, (a, b) -> {
            if (points[a] != points[b]) {
                return Integer.compare(points[a], points[b]);
            }
            return Integer.compare(types[b], types[a]);
        });
        
        List<int[]> merged = new ArrayList<>();
        int count = 0;
        int start = 0;
        
        for (int index : indices) {
            int point = points[index];
            int type = types[index];
            
            if (count == 0) {
                start = point;
            }
            
            count += type;
            
            if (count == 0) {
                int end = point;
                merged.add(new int[]{start, end});
            }
        }
        
        return merged.toArray(new int[merged.size()][]);
    }
}

复杂度分析:

  • 算法的时间复杂度为O(n log n),其中n是区间的数量。这是因为算法涉及对区间的排序操作,而排序的时间复杂度为O(n log n)。
  • 算法的空间复杂度为O(n),用于存储排序后的区间和合并后的结果。

需要注意的是,在最坏情况下,即所有的区间都不重叠时,算法需要将所有区间都合并为一个大区间,此时时间复杂度为O(n)。

总之,本算法的时间复杂度和空间复杂度都是比较优秀的,是解决区间合并问题的一个非常好的算法。

LeetCode运行结果:

方法三:栈

除了排序和遍历、扫描线算法外,还有一种常见的方法是使用栈来合并区间。

具体实现思路如下:

  1. 首先将所有区间按照起始位置进行排序。
  2. 创建一个栈,将第一个区间放入栈中。
  3. 遍历剩余的区间,如果当前区间的起始位置大于栈顶区间的结束位置,说明两个区间不重叠,直接将当前区间入栈。 否则,将当前区间与栈顶区间合并,更新栈顶区间的结束位置为两者中的较大值。
  4. 遍历完所有区间后,栈中存储的就是合并后的区间。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length <= 1) {
            return intervals;
        }
        
        // 根据起始位置对区间进行排序
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        
        // 使用栈来合并区间
        Stack<int[]> stack = new Stack<>();
        stack.push(intervals[0]);
        
        for (int i = 1; i < intervals.length; i++) {
            int[] currentInterval = intervals[i];
            int[] topInterval = stack.peek();
            
            if (currentInterval[0] > topInterval[1]) {
                // 当前区间与栈顶区间不重叠,直接入栈
                stack.push(currentInterval);
            } else {
                // 合并当前区间和栈顶区间
                topInterval[1] = Math.max(topInterval[1], currentInterval[1]);
            }
        }
        
        // 将栈中的区间转化为数组返回
        List<int[]> merged = new ArrayList<>(stack);
        return merged.toArray(new int[merged.size()][]);
    }
}

复杂度分析:

使用栈的方法时间复杂度取决于排序的时间复杂度,因此为 O(n log n),其中n是区间的数量。空间复杂度为O(n),用于存储合并后的区间。

具体分析如下:

  • 对区间进行排序的时间复杂度为 O(n log n),因为我们需要对所有区间按照起始位置进行排序。
  • 遍历整个区间数组的时间复杂度为 O(n),因为我们只需要遍历每个区间一次,并将合并后的区间存储在一个栈中。
  • 最后将栈中的元素转化为二维数组的时间复杂度为 O(n),因为我们需要遍历栈中所有元素一次,并将它们存储在一个二维数组中。

因此,总的时间复杂度为 O(n log n) + O(n) + O(n) = O(n log n)。空间复杂度为O(n),因为我们需要存储合并后的区间。

需要注意的是,排序操作是这种方法的时间复杂度瓶颈,因此如果输入区间已经有序或者近似有序,则使用这种方法可能更加高效,因为排序的时间复杂度可以达到O(n)。但是一般情况下,排序和遍历、扫描线算法仍然是解决区间合并问题的首选方法。

LeetCode运行结果:

第三题

题目来源

57. 插入区间 - 力扣(LeetCode)

题目内容

解决方法

方法一:遍历和比较

思路与算法:

  1. 首先,根据题目要求,我们可以将给定的区间列表按照起始端点进行排序,这样可以方便后续的处理。

  2. 接下来,我们需要遍历排序后的区间列表,逐个与新的区间进行比较和合并。

  3. 初始化一个结果列表 merged,用于存储最终的合并后的区间。

  4. 遍历排序后的区间列表,对于每个区间 intervals[i],与新的区间 newInterval 进行比较和合并。

    • 如果 intervals[i] 的结束位置小于 newInterval 的起始位置,说明两个区间没有重叠,直接将 intervals[i] 加入 merged 中。

    • 如果 intervals[i] 的起始位置大于 newInterval 的结束位置,说明后面的区间也不会有重叠,直接将 newInterval 和后面的区间加入 merged 中,并返回最终结果。

    • 如果 intervals[i] 和 newInterval 存在重叠,我们需要不断地更新 newInterval 的范围,使其包括当前区间 intervals[i] 及可能的后续重叠区间,直到找到一个不与 newInterval 重叠的区间或者完成遍历。

  5. 最后,将 newInterval 添加到 merged 中,并将剩余的 intervals[i] 依次加入 merged。

  6. 返回 merged 列表中的区间数组作为最终结果。

import java.util.ArrayList;
import java.util.List;

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        List<int[]> merged = new ArrayList<>(); // 用于存储合并后的区间
        int i = 0;
        
        // 将起始位置小于newInterval的区间加入结果列表
        while (i < intervals.length && intervals[i][1] < newInterval[0]) {
            merged.add(intervals[i]);
            i++;
        }
        
        // 合并与newInterval相交的区间
        while (i < intervals.length && intervals[i][0] <= newInterval[1]) {
            newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
            newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
            i++;
        }
        
        // 将合并后的newInterval加入结果列表
        merged.add(newInterval);
        
        // 将剩余的区间加入结果列表
        while (i < intervals.length) {
            merged.add(intervals[i]);
            i++;
        }
        
        // 将结果列表转换为数组返回
        return merged.toArray(new int[merged.size()][2]);
    }
}

复杂度分析:

  • 该算法的时间复杂度为 O(n),其中 n 是区间的个数,因为需要遍历整个区间列表一次。
  • 算法中使用了一个额外的空间 merged 来存储合并后的区间,空间复杂度为 O(n),其中 n 是合并后的区间的个数。

LeetCode运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1059343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux进程概念(上)

冯诺依曼体系结构 这里谈论的体系结构指的是计算机组成 常见的计算机&#xff0c;如笔记本&#xff0c;不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系 计算机&#xff0c;都由一个个的硬件组件组成 输入单元&#xff1a;如键盘&#xff0c;…

如何在IIS7里设置实现访问.txt文件是下载模式

如何在IIS7里设置实现访问.txt文件是下载模式 1、打开iis管理器--在网站中点击需要调整的站点&#xff0c;然后在如下图位置点击MIME类型 2、添加一个新的MIME类型&#xff0c;文件扩展名填写 .txt&#xff0c;MIME类型填写application/octet-stream&#xff0c;如下图&#x…

图神经网络 GNN

之前经常看到图神经网络的内容&#xff0c;但是一直都觉得很难&#xff0c;就没有继续了解&#xff0c;现在抽空学习了一下&#xff0c;简单了解GNN是个什么东西&#xff0c;还没有进行代码实践&#xff0c;随着后续的学习&#xff0c;会继续更新代码的内容&#xff0c;这里先记…

Autosar诊断实战系列20-UDS首帧数据接收及流控帧发送代码级分析

本文框架 前言1. 长帧数据的首帧接收2. 首帧数据的处理及流控帧发送2.1 首帧数据的处理2.2 流控帧数据的发送前言 在本系列笔者将结合工作中对诊断实战部分的应用经验进一步介绍常用UDS服务的进一步探讨及开发中注意事项, Dem/Dcm/CanTp/Fim模块配置开发及注意事项,诊断与Bs…

【Redis】数据过期策略和数据淘汰策略

数据过期策略和淘汰策略 过期策略 Redis所有的数据结构都可以设置过期时间&#xff0c;时间一到&#xff0c;就会自动删除。 问题&#xff1a;大家都知道&#xff0c;Redis是单线程的&#xff0c;如果同一时间太多key过期&#xff0c;Redis删除的时间也会占用线程的处理时间…

【C++】STL详解(九)—— set、map、multiset、multimap的介绍及使用

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】STL…

订单型批发制造企业经营分析123个指标大全(ODOO15/16)

ODOO-ERP搭建完成之后&#xff0c;我们重点是帮客户建立经营分析能力&#xff0c;以下是针对订单型企业的经营分析指标&#xff0c;涵盖业务运营的监控、资产构成、利润、盈亏点计算、资产运营效率等各方面&#xff0c;并且持续完善​。 有些企业不重视&#xff0c;觉得自己企业…

基于Java的环境保护宣传管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

前端——html面试题(一)

文章目录 前言一、说说你对 html 语义化的理解。二、html的标签有哪些三、标签类型1、问题&#xff1a;请说说你对块级元素、行内元素、空元素的理解&#xff0c;它们分别都有哪些常见的标签&#xff1f; 总结 前言 说说对html语义化的理解html的标签标签类型 一、说说你对 ht…

基于YOLOv8的安全帽检测系统(3):DCNv3可形变卷积,基于DCNv2优化,助力行为检测 | CVPR2023 InternImage

目录 1.Yolov8介绍 2.安全帽数据集介绍 3.InternImage介绍 4.训练结果分析 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前YOLO成功…

【C语言】汉诺塔 —— 详解

一、介绍 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大焚天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大焚天命令婆罗门把圆盘从下面开始按…

java连接数据库SQL注入问题的解决

演示注入 解决方法把statement类型替换成了preparedstatement类型 其底层原理就是把用户输入的字符串转义了

java使用数据库连接池

我的jar包名字 这些包都可以去搜索,有很多小伙伴会用网盘给我们.导入jar包就是复制然后粘贴就好了

【C语言】归并排序

文章目录 一、什么是归并排序二、归并排序步骤图解三、归并排序代码实现1、递归实现2、非递归实现 四、总结 一、什么是归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列…

抖音聊天对话模板,制作一条一条冒出来的聊天对话短视频

聊天对话模板是一种非常有趣且实用的工具&#xff0c;它主要用于制作抖音聊天记录一条一条冒出来的视频。有了聊天对话模板&#xff0c;你再也不需要费心去写剧本&#xff0c;只需输入一些简单的文案&#xff0c;就能自动生成搞笑对话视频。 聊天对话工具下载&#xff1a; htt…

2023蓝帽杯半决赛电子取证+CTF部分题解

文章目录 电子取证123456789101112131415 CTFWeb | MyLinuxBotWeb | AirticleShareCrypto | ezrsaPwn | AdminPwn | uafmisc|排排坐吃吃果果 电子取证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CTF Web | MyLinuxBot Web | AirticleShare import requests import times reques…

【正点原子】无法打开 源 文件 “linux/time_types.h“ (dependency of “linux/ide.h“)

问题描述 在VS code中些驱动代码时显示&#xff1a; 检测到 #include 错误。请更新 includePath。已为此翻译单元(/home/alientek/linux/atk-mp1/Linux_Drivers/2_LED/led.c)禁用波形曲线。C/C(1696) 无法打开 源 文件 "linux/time_types.h" (dependency of "…

前端开发、后端开发与全栈开发:构建现代网站的全面视角

探讨前端开发、后端开发和全栈开发的概念和在构建现代网站和应用程序中的作用。随着技术的快速发展和市场竞争的加剧&#xff0c;理解和掌握这三种开发角色对于构建成功的数字产品至关重要。 一、前端开发&#xff1a;用户体验的核心 前端开发者主要负责构建用户与服务器交互…

JUC——原子类

1.基本类型原子操作类 AtomicInteger&#xff1a;整型原子类 AtomicBoolean&#xff1a;布尔型原子类 AtomicLong&#xff1a;长整型原子类 1.1常用API public final int get() //获取当前的值 public final int getAndSet(int newValue)//获取当前的值&#xff0c;并设置…

Linux shell编程学习笔记7:只读变量

在编程过程中&#xff0c;我们经常会使用到一些常量&#xff0c;也就是值不需要改变的变量&#xff0c;在许多编程语言提供了常量的定义方式&#xff0c;比如c/c的define MAXNUM 99999 或 const int a 7&#xff0c;javasccipt的const a7&#xff0c; 等等。 跟以上这些方法…