怒刷LeetCode的第19天(Java版)

news2024/11/24 9:53:57

目录

第一题

题目来源

题目内容

解决方法

方法一:遍历一次数组

方法二:贪心算法

方法三:双指针

第二题

题目来源

题目内容

解决方法

方法一:动态规划

方法二:贪婪算法

方法三:正则表达式

第三题

题目来源

题目内容

解决方法

方法一:贪心算法

方法二:动态规划

方法三:广度优先搜索

方法四:逆向贪婪算法



第一题

题目来源

605. 种花问题 - 力扣(LeetCode)

题目内容

解决方法

方法一:遍历一次数组

该问题的思路与算法如下:

  1. 初始化一个计数器count为0,用于记录可以种植花的数量。
  2. 遍历花坛数组,检查每个位置是否可以种植花。
    • 如果当前位置为0,且其相邻的两个位置也为0(或者是边界情况),则该位置可以种植花。将该位置设为1,计数器count加1。
  3. 遍历结束后,判断计数器count的值是否大于等于n。
    • 如果是,则表示可以种入n朵花,返回true。
    • 如果不是,则表示不能种入n朵花,返回false。

这个思路的关键在于遍历花坛数组,检查每个位置是否满足种植花的条件。需要注意边界情况的处理,即第一个位置和最后一个位置的相邻位置的判断条件略有不同。通过遍历一次数组,可以快速判断能否种入n朵花。时间复杂度为O(n),其中n为花坛数组的长度。

class Solution {
public static boolean canPlaceFlowers(int[] flowerbed, int n) {
        int count = 0;
        int length = flowerbed.length;
        int i = 0;

        while (i < length) {
            if (flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == length - 1 || flowerbed[i + 1] == 0)) {
                flowerbed[i] = 1;
                count++;
            }
            i++;

            if (count >= n) {
                return true;
            }
        }

        return false;
    }
}

复杂度分析:

  • 时间复杂度:遍历一次花坛数组,对于每个位置最多访问其相邻的两个位置,因此时间复杂度为O(n),其中n为花坛数组的长度。
  • 空间复杂度:该算法只使用了常数个变量,因此空间复杂度为O(1)。

综上所述,该算法的时间复杂度为O(n),空间复杂度为O(1)。

LeetCode运行结果:

方法二:贪心算法

除了遍历数组的解法,还可以使用贪心算法来解决这个问题。具体思路是:从左到右遍历花坛数组,如果当前位置为0且其相邻的左右位置都是0,则在该位置种植花,并将计数器加1;如果当前位置为1,则直接跳到下一个位置。

使用贪心算法的好处在于避免了对整个数组的遍历,而是仅仅关注每个位置是否能够种植花。这样可以优化时间复杂度,使得算法的运行时间更快。

class Solution {
public static boolean canPlaceFlowers(int[] flowerbed, int n) {
        int count = 0;
        int i = 0;

        while (i < flowerbed.length) {
            if (flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.length - 1 || flowerbed[i + 1] == 0)) {
                flowerbed[i] = 1;
                count++;
            }
            i++;
        }

        return count >= n;
    }
}

复杂度分析:

  • 时间复杂度: 这个解法只需要遍历一次花坛数组,对于每个位置最多访问其相邻的两个位置。因此,时间复杂度为 O(n),其中 n 是花坛数组的长度。
  • 空间复杂度: 该解法只使用了常数个变量,所以空间复杂度为 O(1)。

综上所述,使用贪心算法的解法的时间复杂度为 O(n),空间复杂度为 O(1)。与遍历数组的解法相比,在时间复杂度上并无区别,但是在代码实现上更简洁。

LeetCode运行结果:

方法三:双指针

除了遍历数组、贪心算法,还可以使用双指针来解决这个问题。

具体思路是使用两个指针,一个指向当前位置,一个指向前一个位置。从左到右遍历花坛数组,如果当前位置为0且前一个位置和后一个位置都是0,则在该位置种植花,并将计数器加1。然后将两个指针向后移动两位,继续遍历下一个位置。

class Solution {
public static boolean canPlaceFlowers(int[] flowerbed, int n) {
        int count = 0;
        int i = 0;

        while (i < flowerbed.length) {
            if (flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.length - 1 || flowerbed[i + 1] == 0)) {
                flowerbed[i] = 1;
                count++;
                i += 2;
            } else {
                i++;
            }
        }

        return count >= n;
    }
}

复杂度分析:

  • 时间复杂度:O(n),其中n为花坛数组的长度。
  • 空间复杂度:O(1),只需要常数级别的额外空间存储临时变量。

与贪心算法相比,在思路上稍微有所不同,但在时间复杂度和空间复杂度上相同。

LeetCode运行结果:

第二题

题目来源

44. 通配符匹配 - 力扣(LeetCode)

题目内容

解决方法

方法一:动态规划

这个问题可以使用动态规划的思路来解决。

我们可以定义一个二维布尔数组dp,其中dp[i][j]表示字符串s的前i个字符和模式串p的前j个字符是否匹配。

接下来我们分析状态转移的情况:

  1. 当s的第i个字符和p的第j个字符相等或者p的第j个字符为'?'时,dp[i][j]的值取决于dp[i-1][j-1],即s的前i-1个字符和p的前j-1个字符是否匹配。
  2. 当p的第j个字符为'*'时,dp[i][j]的值可以从dp[i][j-1]或dp[i-1][j]转移而来:
    • dp[i][j-1]表示'*'匹配了空字符,此时dp[i][j]的值取决于dp[i][j-1];
    • dp[i-1][j]表示'*'匹配了s的第i个字符,此时dp[i][j]的值取决于dp[i-1][j]。

根据以上分析,我们可以得到动态规划的状态转移方程:

if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
    dp[i][j] = dp[i - 1][j - 1];
} else if (p.charAt(j - 1) == '*') {
    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
}

边界情况:

  • dp[0][0]表示空字符和空字符完全匹配,初始化为true;
  • dp[0][j]表示空字符和模式串p的前j个字符匹配的情况。若p的第j个字符为'*',则dp[0][j]的值取决于dp[0][j-1];否则为false;
  • dp[i][0]表示字符串s的前i个字符和空字符匹配的情况,都为false。

最终,我们返回dp[m][n],即字符串s的全部字符和模式串p的全部字符是否完全匹配。

class Solution {
    public boolean isMatch(String s, String p) {
        int m = s.length(), n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;

        // 处理 p 以 * 开头的情况
        for (int j = 1; j <= n; j++) {
            if (p.charAt(j - 1) == '*') {
                dp[0][j] = true;
            } else {
                break;
            }
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (p.charAt(j - 1) == '*') {
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                }
            }
        }

        return dp[m][n];
    }
}

复杂度分析:

对于给定长度为m的字符串s和长度为n的模式串p,动态规划解法的时间复杂度为O(mn),空间复杂度也为O(mn)。

在计算过程中,我们需要填充一个大小为(m+1)×(n+1)的二维dp数组。每个位置的填充操作需要常数时间,因此总的时间复杂度为O(m*n)。

同时,我们只使用一个二维dp数组来存储中间结果,所以空间复杂度也是O(m*n)。

需要注意的是,这里的m和n并不是指s和p的最大长度,而是分别表示s和p实际的长度加1。这是因为我们在填充dp数组时,需要考虑到空字符和空模式串的情况。

总结起来,该解法具有较优的时间和空间复杂度,适用于处理规模较小的字符串匹配问题。

LeetCode运行结果:

方法二:贪婪算法

除了动态规划,还可以使用贪婪算法进行字符串匹配。贪婪算法通常是一种基于局部最优选择的策略,在某些情况下可以得到快速且有效的解。具体到字符串匹配问题,我们可以通过迭代遍历的方式来实现贪婪算法。

该贪婪算法的思路是一次处理字符串s和模式串p的一个字符,根据当前的字符匹配情况进行不同操作:

  • 若两个字符相等或者模式串p的当前字符为'?',则两个索引都向后移动;
  • 若模式串p的当前字符为'*',记录当前位置,并只移动模式串的索引;
  • 若当前字符不匹配,但之前出现过''的情况,回溯到''匹配的下一个位置,并将字符串索引+1;
  • 若没有之前出现过'*'的情况,则匹配失败。
  • 最后需要处理模式串p末尾的多余字符,判断是否全部为'*'。

该贪婪算法在某些情况下可以得到快速的解,但并不适用于所有的字符串匹配问题。在一些特殊的模式串情况下,可能会导致错误的匹配结果。因此,在实际应用中,需要根据具体情况选择合适的解法。

class Solution {
    public boolean isMatch(String s, String p) {
        int sIndex = 0; // 字符串s的索引
        int pIndex = 0; // 模式串p的索引
        int matchIndex = -1; // 最近一次出现'*'匹配的位置
        int starIndex = -1; // 最近一次出现'*'的位置

        while (sIndex < s.length()) {
            // 当两个字符相等或模式串为'?'时,两个索引都向后移动
            if (pIndex < p.length() && (s.charAt(sIndex) == p.charAt(pIndex) || p.charAt(pIndex) == '?')) {
                sIndex++;
                pIndex++;
            }
            // 当模式串为'*'时,记录当前位置,并只移动模式串的索引
            else if (pIndex < p.length() && p.charAt(pIndex) == '*') {
                starIndex = pIndex;
                matchIndex = sIndex;
                pIndex++;
            }
            // 当前字符不匹配,但有之前出现过'*'的情况,回溯到'*'匹配的下一个位置,并将字符串索引+1
            else if (starIndex != -1) {
                pIndex = starIndex + 1;
                matchIndex++;
                sIndex = matchIndex;
            }
            // 当没有之前出现过'*'的情况,返回false
            else {
                return false;
            }
        }

        // 处理模式串末尾的多余字符
        while (pIndex < p.length() && p.charAt(pIndex) == '*') {
            pIndex++;
        }

        // 字符串s和模式串p都遍历完毕,则匹配成功
        return pIndex == p.length();
    }
}

复杂度分析:

设字符串 s 的长度为 n,模式串 p 的长度为 m。

  • 在最坏情况下(即没有匹配的字符和通配符时),两个索引 sIndex 和 pIndex 都要遍历整个字符串 s 和模式串 p。 时间复杂度为 O(n+m)。
  • 在处理通配符 '*' 时,如果出现回溯的情况,需要在每次回溯时移动 pIndex 和 matchIndex,直到找到匹配的字符位置。 由于每次回溯都会移动 sIndex,所以总共只会有 n 次回溯操作。 因此,在最坏情况下,回溯操作的时间复杂度为 O(n)。
  • 在处理模式串末尾的多余字符时,需要遍历剩余的模式串字符。 时间复杂度为 O(m-pIndex)。

综上所述,代码的总体时间复杂度为 O(n+m),空间复杂度为 O(1)。

LeetCode运行结果:

方法三:正则表达式
class Solution {
    public boolean isMatch(String s, String p) {
        String regex = p.replace("?", ".")
                        .replace("*", ".*");
        return s.matches(regex);
    }
}

这个实现使用了 Java 的正则表达式来处理通配符匹配。首先,将模式串 p 中的 '?' 替换成 '.',将 '' 替换成 '.',得到一个新的正则表达式 regex。

然后,使用字符串 s 的 matches() 方法,测试字符串 s 是否能够匹配正则表达式 regex。如果能够匹配,则返回 true,否则返回 false。

需要注意的是,该方法只是一种简单的通配符匹配算法,可能无法处理一些复杂的情况。在实际应用中,需要根据需求选择更加高效和精确的算法。

复杂度分析:

  • 时间复杂度分析:使用正则表达式的 matches() 方法进行匹配,具体的实现和性能取决于底层正则引擎。一般情况下,时间复杂度为 O(M*N),其中 M 是模式串 p 的长度,N 是字符串 s 的长度。
  • 空间复杂度分析:空间复杂度取决于正则表达式的匹配过程中是否需要生成匹配结果的存储。在 Java 的 matches() 方法中,会将整个匹配结果存储在内存中,并返回一个 boolean 值表示是否匹配成功。因此,空间复杂度为 O(M*N),其中 M 是模式串 p 的长度,N 是字符串 s 的长度。

LeetCode运行结果:

第三题

题目来源

45. 跳跃游戏 II - 力扣(LeetCode)

题目内容

解决方法

方法一:贪心算法
class Solution {
    public int jump(int[] nums) {
        if (nums.length <= 1) {
            return 0;
        }

        int maxReach = nums[0]; // 当前能够到达的最远位置
        int steps = nums[0]; // 当前步数内能够到达的最远位置
        int jumps = 1; // 跳跃次数

        for (int i = 1; i < nums.length; i++) {
            // 如果当前位置超过了最远位置,需要进行一次跳跃
            if (i > maxReach) {
                jumps++;
                maxReach = steps;
            }
            
            // 更新当前步数内能够到达的最远位置
            steps = Math.max(steps, i + nums[i]);
        }

        return jumps;
    }
}

在这个实现中,我们使用贪心算法来寻找最优解。我们定义三个变量:

  • maxReach:当前能够到达的最远位置
  • steps:当前步数内能够到达的最远位置
  • jumps:跳跃次数

我们从索引 1 开始遍历数组,每次更新 steps 的值为当前位置加上当前元素的值。如果当前位置超过了 maxReach,说明我们需要进行一次跳跃,此时将 jumps 加 1,并更新 maxReach 为 steps。

最终,返回 jumps 的值即为到达最后一个位置的最小跳跃次数。

复杂度分析:

  • 时间复杂度是 O(n),其中 n 是数组 nums 的长度。这是因为我们只需要遍历一次数组,每次遍历都更新跳跃的最远位置和步数内能够到达的最远位置。
  • 空间复杂度是 O(1),即常数级别的额外空间。这是因为我们只使用了几个变量来保存最远位置、步数和跳跃次数,没有使用额外的数组或数据结构。

因此,该算法是一个高效的解决方案,可以在给定的约束条件下快速求解跳跃游戏问题。

LeetCode运行结果:

方法二:动态规划

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

class Solution {
    public int jump(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n]; // dp[i] 表示到达第 i 个位置所需的最小跳跃次数

        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;

        for (int i = 0; i < n; i++) {
            int maxJump = nums[i]; // 当前位置能够跳跃的最大长度

            for (int j = 1; j <= maxJump && i + j < n; j++) {
                dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
            }
        }

        return dp[n - 1];
    }
}

在这个实现中,我们首先创建一个长度为 n 的数组 dp,用于保存到达每个位置所需的最小跳跃次数。初始化 dp[0] 为 0,其它位置的值都设置为一个较大的数,表示初始状态为无穷大。

然后,我们从左向右遍历数组 nums,对于每个位置 i,将当前位置能够跳跃的最大长度 nums[i] 内的所有位置的 dp 值更新为 dp[i] + 1,表示通过当前位置 i 进行一次跳跃。

最终,返回 dp[n - 1] 的值即为到达最后一个位置的最小跳跃次数。

该算法的时间复杂度是 O(n^2),其中 n 是数组 nums 的长度。因为我们需要遍历每个位置,并且对于每个位置,还需要遍历当前位置能够跳跃的最大长度内的所有位置。

复杂度分析:

  • 时间复杂度是 O(n^2),其中 n 是数组 nums 的长度。这是因为我们需要遍历每个位置,并对于每个位置,还需要遍历当前位置能够跳跃的最大长度内的所有位置。
  • 空间复杂度是 O(n),即额外使用了一个数组 dp 来保存最小跳跃次数。这是因为我们需要存储到达每个位置所需的最小跳跃次数。

虽然动态规划解法的时间复杂度较高,但它提供了一种通用的解决方法,适用于各种求解最优解问题的场景。在实际应用中,可以根据输入规模和实际需求来选择贪心算法或动态规划来解决跳跃游戏问题。如果输入规模较小,动态规划算法的性能可能会比较好;如果输入规模较大,贪心算法可能会更加高效。

LeetCode运行结果:

方法三:广度优先搜索

除了贪婪算法和动态规划之外,还有一种常见的解决方法是使用广度优先搜索(BFS)。

import java.util.LinkedList;
import java.util.Queue;

class Solution {
    public int jump(int[] nums) {
        int n = nums.length;

        if (n == 1) {
            return 0; // 如果数组长度为 1,则不需要跳跃
        }

        Queue<Integer> queue = new LinkedList<>(); // 用于保存当前位置的队列
        boolean[] visited = new boolean[n]; // 记录每个位置是否已访问
        visited[0] = true;
        queue.offer(0); // 将起始位置加入队列
        int step = 0; // 跳跃的次数

        while (!queue.isEmpty()) {
            int size = queue.size();

            for (int i = 0; i < size; i++) {
                int currIndex = queue.poll();
                int maxJump = nums[currIndex];

                for (int j = 1; j <= maxJump; j++) {
                    int nextIndex = currIndex + j;

                    if (nextIndex >= n - 1) {
                        // 如果能够跳到最后一个位置或超过最后一个位置,则返回当前步数+1
                        return step + 1;
                    }

                    if (!visited[nextIndex]) {
                        visited[nextIndex] = true;
                        queue.offer(nextIndex);
                    }
                }
            }

            step++;
        }

        return -1; // 如果无法达到最后一个位置,则返回 -1
    }
}

在这个实现中,我们使用一个队列 queue 来广度优先搜索每个位置能够跳跃到的下一个位置。

  1. 初始时,我们将起始位置加入队列,并将其标记为已访问。
  2. 然后,我们不断从队列中取出当前位置,遍历它能够跳跃的最大长度内的所有位置。如果遍历过程中发现某个位置能够跳到最后一个位置或超过最后一个位置,则返回当前步数+1,表示跳跃结束。
  3. 如果无法达到最后一个位置,则返回 -1。

复杂度分析:

时间复杂度:

  • 遍历数组的过程中,每个位置最多会被访问一次,因此遍历数组的时间复杂度是 O(n)。
  • 在最坏情况下,队列中的元素数量可以达到 n,每个元素都需要进行扩展操作。在每个扩展操作中,需要遍历当前位置能够跳跃的最大长度内的所有位置。由于最大跳跃长度的上限是 n,因此每个位置进行扩展操作的时间复杂度是 O(n)。总的时间复杂度是 O(n^2)。

空间复杂度:

  • 使用一个队列来保存当前位置,队列的最大长度不会超过 n,因此队列的空间复杂度是 O(n)。
  • 使用一个布尔数组 visited 来记录已访问的位置,数组的长度与数组 nums 的长度相同,因此布尔数组的空间复杂度也是 O(n)。
  • 总的空间复杂度是 O(n)。

需要注意的是,由于贪婪算法的效率更高,动态规划和广度优先搜索通常在处理较大输入规模时才会被使用。在小规模问题上,贪婪算法往往是更快的解决方法。

LeetCode运行结果:

方法四:逆向贪婪算法

除了贪婪算法、动态规划和广度优先搜索,还有另外一种常用的解决方法,称为跳跃游戏问题的逆向贪婪算法。

逆向贪婪算法的基本思路是从目标位置开始向起始位置遍历,每次选择能够到达当前位置的最远跳跃位置作为新的目标位置,直到遍历到起始位置为止。这样可以得到从起始位置到目标位置的最小跳跃次数。

class Solution {
    public int jump(int[] nums) {
        int position = nums.length - 1;
        int jumps = 0;
        
        while (position > 0) {
            for (int i = 0; i < position; i++) {
                if (i + nums[i] >= position) {
                    position = i;
                    jumps++;
                    break;
                }
            }
        }
        
        return jumps;
    }
}

在这个实现中,我们使用变量 position 来表示当前的目标位置,初始化为数组的最后一个位置。变量 jumps 记录跳跃次数,初始化为 0。

通过一个循环,我们从目标位置开始向起始位置遍历。内层循环遍历从当前位置到目标位置之间的所有位置,找到第一个能够跳跃到目标位置的位置,更新 position 和 jumps,然后继续向前遍历。

最终,返回 jumps 作为结果。

复杂度分析:

时间复杂度:

  • 遍历数组进行内层循环时,最多需要执行 n 次,其中 n 是数组 nums 的长度。因此,内层循环的时间复杂度是 O(n)。
  • 外层循环从目标位置开始,通过不断更新目标位置进行遍历,最多执行 n-1 次。因此,外层循环的时间复杂度是 O(n)。 综合起来,逆向贪婪算法的时间复杂度是 O(n)。

空间复杂度:

  • 逆向贪婪算法只使用了常数级别的变量,没有使用额外的空间。因此,空间复杂度是 O(1)。

总结起来,逆向贪婪算法是一种时间复杂度为 O(n),空间复杂度为 O(1) 的解决方法。相比于动态规划和广度优先搜索等其他方法,它具有更低的时间复杂度,但需要注意的是,逆向贪婪算法的前提是能够到达目标位置,否则会陷入无限循环。

LeetCode运行结果:

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

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

相关文章

基础算法--KMP字符串

KMP 算法是一个快速查找匹配串的算法&#xff0c;它的作用其实就是本题问题&#xff1a;如何快速在「原字符串」中找到「匹配字符串」。 在朴素解法中&#xff0c;不考虑剪枝的话复杂度是 O(m∗n) 的&#xff0c;而 KMP 算法的复杂度为 O(mn)。 KMP 之所以能够在O(mn) 复杂度内…

成都优优聚公司是靠谱的吗?

成都优优聚公司专业美团代运营团队&#xff0c;以高效、专业、全面的服务赢得了众多客户的青睐。作为一家在美团代运营行业具备丰富经验和优质资源的公司&#xff0c;我们始终以客户的需求为导向&#xff0c;致力于为客户打造出色的美团线上运营方案。 我们公司拥有一支经验丰富…

设计模式探索:从理论到实践的编码示例 (软件设计师笔记)

&#x1f600;前言 设计模式&#xff0c;作为软件工程领域的核心概念之一&#xff0c;向我们展示了开发过程中面对的典型问题的经典解决方案。这些模式不仅帮助开发者创建更加结构化、模块化和可维护的代码&#xff0c;而且也促进了代码的复用性。通过这篇文章&#xff0c;我们…

处理不平衡数据的十大Python库

数据不平衡是机器学习中一个常见的挑战&#xff0c;其中一个类的数量明显超过其他类&#xff0c;这可能导致有偏见的模型和较差的泛化。有各种Python库来帮助有效地处理不平衡数据。在本文中&#xff0c;我们将介绍用于处理机器学习中不平衡数据的十大Python库&#xff0c;并为…

面向对象之旅:核心理念、设计方法与UML详解(软件设计师笔记)

&#x1f600;前言 面向对象技术是现代软件工程的核心&#xff0c;为软件设计和开发带来了一种强大且有序的方法。通过将现实世界的实体和概念映射到可操作的代码结构&#xff0c;该技术使我们能够更高效、清晰和可靠地创建复杂的软件系统。在本章中&#xff0c;我们将详细介绍…

我的国庆回家之路

文章目录 回家的计划假期的礼物学习新技术与家人团聚遇到的趣事总结 &#x1f389;欢迎来到IT陈寒的博客空间~我的国庆回家之路 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1…

【运维日常】华为云专线实现idc通过nat出网

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

【VUE复习·9】v-for 基础用法(循环渲染也叫列表渲染)

总览 1.v-for 都能循环什么 2.用法 一、v-for 都能遍历什么 能循环的东西包括&#xff1a;数组、对象、字符串&#xff08;和java里面的3个引用数据类型一样&#xff09;、纯粹循环数量&#xff08;少用&#xff09; 二、用法 1.用法1&#xff1a;简单循环&#xff08;遍历…

开源协作开发者内容平台Vrite

什么是 Vrite &#xff1f; Vrite 是一个开源协作空间&#xff0c;用于创建、管理和部署产品文档、技术博客和知识库。它旨在提供高质量、集成的用户和开发人员体验。 Vrite 具有以下功能&#xff1a; 内置管理仪表板&#xff0c;用于使用看板或列表视图管理内容生产和交付&am…

亘古难题:前端开发 or 后端开发

目录 一、引言二、两者的对比分析1. 技能要求和专业知识前端开发后端开发 2. 职责和工作内容前端开发后端开发 3. 项目类型和应用领域前端开发后端开发 4. 就业前景和市场需求前端开发后端开发 三、技能转换和跨领域工作四、介绍全栈开发五、结语附、开源项目微服务商城项目前后…

Java获取给定月份的前N个月份和前N个季度

描述&#xff1a; 在项目开发过程中&#xff0c;遇到这样一个需求&#xff0c;即&#xff1a;给定某一月份&#xff0c;得到该月份前面的几个月份以及前面的几个季度。例如&#xff1a;给定2023-09&#xff0c;获取该月份前面的前3个月&#xff0c;即2023-08、2023-07、2023-0…

2023/9/30 -- ARM

今日任务&#xff1a;消息队列实现进程之间通信方式代码&#xff0c;现象 msgW.c: #include <myhead.h> //消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //…

cesium源码无法更新的解决方案

一、环境&#xff1a; 中国移动的宽带 win10操作系统 二、问题复现步骤&#xff1a; 1、开了VPN&#xff0c;设置为全局代理 2、在vscode中执行git pull命令 3、结果显示无法更新 三、解决方案&#xff1a; 1、安装Github官方开发的软件Github Desktop 下载地址&#xf…

(二)Python编程环境搭建

本章重点介绍 Python 编程环境的搭建&#xff0c;包括各个平台下 Python 的下载和安装&#xff0c;常见 IDE 的使用&#xff0c;如何运行 Python 程序等。还会亲自带着大家编写并运行第一个 Python 程序&#xff0c;让大家认识一下最简单的 Python 代码。 本章的后半部分还介绍…

【C++】C++多态——实现、重写、抽象类、原理

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

百度面试题:为什么使用接口而不是直接使用具体类?

大家好&#xff0c;我是小米&#xff01;今天&#xff0c;我要和大家聊聊一个在 Java 编程中非常重要的话题&#xff1a;“百度面试题&#xff1a;为什么要使用接口而不是直接使用具体类&#xff1f;”这个问题在很多 Java 面试中都会被问到&#xff0c;因为它涉及到了面向对象…

基于Java的学校运动会信息管理系统设计与实现(源码+lw+部署文档+讲解等)

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

mysql的mvcc详解

一 MVCC的作用 1.1 mvcc的作用 1.MVCC&#xff08;Multiversion Concurrency Control&#xff09;多版本并发控制。即通过数据行的多个版本管理来实现数据库的并发控制&#xff0c;使得在InnoDB事务隔离级别下执行一致性读操作有了保障。 2.mysql中的InnoDB中实现了MVCC主要…

力扣146|LRU缓存淘汰算法

LRU缓存淘汰算法 leet code146: https://leetcode.cn/problems/lru-cache 一、基本思想 1.1 基本思想 LRU全名Last Recently Used&#xff0c;即当缓存空间满时&#xff0c;优先淘汰最不常使用&#xff08;访问&#xff09;的缓存。 1.2 抽象接口 1、 init() 初始化大小为…

ITSM和ITIL有什么区别?

ITIL是最广泛接受的ITSM方法&#xff0c;是用于管理组织IT运营和服务的最佳实践和建议的框架。它是由英国政府的中央计算机和电信局&#xff08;CCTA&#xff09;在1980年代中期委托创建的。基于ITIL框架构建的ITSM流程为更好的IT服务和改善业务铺平了道路。总而言之&#xff0…