怒刷LeetCode的第16天(Java版)

news2024/11/25 2:33:51

目录

第一题

题目来源

题目内容

解决方法

方法一:迭代

方法二:模拟

方法三:循环模拟

方法四:传递

第二题

题目来源

题目内容

解决方法

方法一:回溯

方法二:枚举优化

第三题

题目来源

题目内容

解决方法

方法一:递归

方法二:迭代

方法三:动态规划

方法四:递推


第一题

题目来源

2582. 递枕头 - 力扣(LeetCode)

题目内容

解决方法

方法一:迭代

这个问题可以使用一个简单的循环来解决。我们使用两个变量来追踪当前拿着枕头的人的位置和传递的方向。

  1. 首先,我们初始化forward为true,表示初始传递方向是向前的。然后,我们进入一个循环,从1到time进行迭代,模拟枕头传递的过程。
  2. 在循环中,我们首先检查当前拿着枕头的人是否处于队列的首位(即pos == 1),如果是,则将传递方向设置为向前(forward = true);然后,我们检查当前拿着枕头的人是否处于队列的末尾(即pos == n),如果是,则将传递方向设置为向后(forward = false)。
  3. 接下来,我们根据传递方向更新当前拿着枕头的人的位置。如果传递方向是向前(forward = true),则将pos加1;如果传递方向是向后(forward = false),则将pos减1。
  4. 重复这个过程,直到达到指定的传递时间time。最后,返回拿着枕头的人的编号pos。

总结来说,我们使用一个循环来迭代传递过程,并根据当前位置和传递方向进行更新,直到达到指定的传递时间。最终,返回拿着枕头的人的编号。

class Solution {
    public int passThePillow(int n, int time) {
        boolean forward = true;
        int pos = 1;

        for (int i = 1; i <= time; i++) {
            if (pos == 1) {
                forward = true;
            } else if (pos == n) {
                forward = false;
            }
            if (forward) {
                pos++;
            } else {
                pos--;
            }
        }
        return pos;
    }
}

复杂度分析:

  • 时间复杂度分析:循环的次数取决于传递的时间time,因此循环的次数是常数级别的。所以,时间复杂度可以表示为O(1),即常数时间复杂度。
  • 空间复杂度分析:在这个算法中,并没有使用任何额外的数据结构,只使用了几个整型变量来追踪位置和方向。因此,空间复杂度是O(1),即常数空间复杂度。

综上所述,该算法具有常数级别的时间复杂度和空间复杂度。这意味着无论输入的传递时间time和参与传递的人数n有多大,算法的执行时间和空间占用都是固定的。

LeetCode运行结果:

方法二:模拟

这个算法的思路是通过观察规律,找到一个公式计算出时间t后枕头所在位置的编号。

首先,我们可以注意到,每当枕头到达队伍的某一端,就会改变传递方向。也就是说,枕头的传递方向是周期性的,以(n-1)*2为一个周期。例如,当n=4时,第一次周期内,枕头的传递顺序是1-2-3-4-3-2;第二次周期内,枕头的传递顺序是2-3-4-3-2-1。因此,我们可以将time对于一个周期取模,以便更好地处理时间过长的情况。

接下来,考虑如何计算枕头所在位置的编号。如果time小于n,此时枕头仍然在最开始的n个人中间传递,因此枕头的位置等于time+1。否则,枕头已到达了队伍的另一端,需要反向传递。如果按顺序数枕头位置,此时与time相对应的枕头位置应该是n*2-time-1,因此可以使用这个表达式计算枕头所在的位置编号。

class Solution {
    public int passThePillow(int n, int time) {
        time %= (n - 1) * 2;
        return time < n ? time + 1 : n * 2 - time - 1;
    }
}

复杂度分析:

  • 时间复杂度分析:在这个算法中,我们只有一个简单的求模运算和一个条件判断,所以时间复杂度为O(1),即常数时间复杂度。
  • 空间复杂度分析:该算法没有使用任何额外的数据结构或递归调用,所以空间复杂度为O(1),即常数空间复杂度。不论输入的大小,所需的额外空间都是固定的。

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

LeetCode运行结果:

方法三:循环模拟

这个算法的思路是使用一个循环来模拟枕头传递过程,每次选择下一个接收枕头的人的位置。

  1. 首先,我们初始化两个变量ans和k,分别表示当前枕头所在的位置和传递的方向。初始时,枕头在位置1,传递方向为向右。
  2. 然后,我们进入一个循环,循环执行time次。在每一次循环中,首先将ans的值增加k,以选取下一个接收枕头的位置(如果k为1,则向右移动一位;如果k为-1,则向左移动一位)。然后,如果ans等于1或者等于n,表示枕头到达队伍的一端,需要改变传递方向,即将k乘以-1。
  3. 重复上述步骤,直到循环执行完time次,最后返回ans即为最终枕头所在的位置编号。
class Solution {
    public int passThePillow(int n, int time) {
        int ans = 1, k = 1;
        while (time-- > 0) {
            ans += k;
            if (ans == 1 || ans == n) {
                k *= -1;
            }
        }
        return ans;
    }
}

复杂度分析:

  • 时间复杂度分析:在这个算法中,循环执行time次,因此时间复杂度为O(time)。虽然time是一个变量,但是在实际应用中,time一般是一个较小的固定值。
  • 空间复杂度分析:该算法只使用了几个整型变量,不随输入规模变化,因此空间复杂度为O(1),即常数空间复杂度。

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

LeetCode运行结果:

方法四:传递

这个算法的思路是,先计算出枕头到达队伍的另一端需要经过几次传递,然后根据剩余传递次数和当前位置计算最终位置。

  • 首先,我们可以注意到,在N个人的队伍中,每当枕头到达队伍的某一端,就会经过N-1个人的传递。也就是说,每N-1个传递为一个周期,枕头在经过一个周期后,就会回到原来的位置并改变传递方向。因此,我们可以先计算出枕头要经过几个周期才能到达队伍的另一端。
  • 接着,我们将time除以n-1得到k,表示枕头需要经过k个周期。然后,对n-1取模得到mod,表示枕头在进行完k个周期后还要经过mod次传递。
  • 最后,我们根据当前位置和剩余传递次数计算最终位置。如果经过k个周期后,枕头处于队伍的左侧(即k为偶数),则最终位置为当前位置加上mod;否则,最终位置为n-mod(反向传递)。
class Solution {
    public int passThePillow(int n, int time) {
        int k = time / (n - 1);
        int mod = time % (n - 1);
        return (k & 1) == 1 ? n - mod : mod + 1;
    }
}

复杂度分析:

  • 时间复杂度分析:在这个算法中,我们只进行了几次简单的整数运算,因此时间复杂度为O(1),即常数时间复杂度。
  • 空间复杂度分析:该算法只使用了几个整型变量,不随输入规模变化,因此空间复杂度为O(1),即常数空间复杂度。

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

LeetCode运行结果:

第二题

题目来源

37. 解数独 - 力扣(LeetCode)

题目内容

解决方法

方法一:回溯

这道题可以通过回溯算法来解决。回溯算法是一种暴力搜索的算法,它尝试在数独的空格中填入数字,并检查填入是否满足数独的规则。如果满足,则继续下一个空格;如果不满足,则回退到上一个空格重新选择数字。

具体实现时,可以使用递归函数来进行回溯。递归函数的参数可以包括数独数组、当前要填入的行和列。在每个空格中,我们尝试填入数字 1-9,并检查是否满足数独的规则。如果满足,则递归调用下一个空格;如果不满足,则尝试下一个数字。直到填完所有的空格,或者找到了一个有效的解为止。

class Solution {
    public void solveSudoku(char[][] board) {
        if (board == null || board.length == 0) {
            return;
        }
        solve(board);
    }

    private boolean solve(char[][] board) {
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (board[row][col] == '.') {
                    for (char num = '1'; num <= '9'; num++) {
                        if (isValid(board, row, col, num)) {
                            board[row][col] = num;
                            if (solve(board)) {
                                return true;
                            } else {
                                board[row][col] = '.'; // 回溯
                            }
                        }
                    }
                    return false; // 所有数字都尝试过都不满足条件,返回false
                }
            }
        }
        return true; // 数独已填满,返回true
    }

    private boolean isValid(char[][] board, int row, int col, char num) {
        for (int i = 0; i < 9; i++) {
            if (board[i][col] == num) { // 检查列是否重复
                return false;
            }
            if (board[row][i] == num) { // 检查行是否重复
                return false;
            }
            int subBoxRow = 3 * (row / 3) + i / 3; // 检查小宫格是否重复
            int subBoxCol = 3 * (col / 3) + i % 3;
            if (board[subBoxRow][subBoxCol] == num) {
                return false;
            }
        }
        return true;
    }
}

复杂度分析:

时间复杂度:

  • 遍历数独空格:O(81),因为数独是固定的9x9大小,所以遍历所有的空格需要O(81)的时间复杂度。
  • 递归尝试填入数字:在每个空格中,我们尝试填入1-9的数字,所以对于每个空格,尝试的次数为常数,所以总的尝试次数为O(1)。
  • 判断填入的数字是否满足数独规则:在判断一个数字在行、列、3x3宫格中是否重复时,我们需要遍历相关的行、列和宫格,每次都是常数时间操作,所以总的判断时间为O(1)。 综上所述,整个数独解法的时间复杂度为O(81 * 1 * 1) = O(81)。

空间复杂度:

  • 递归栈空间:递归函数的调用会使用一定的栈空间,递归的最大深度不会超过空格的数量,所以空间复杂度为O(m),其中m是空格的数量。对于数独问题来说,空格的数量最多为81个,所以空间复杂度为O(81) = O(1)。
  • 数独数组修改:原地修改数独数组,不需要使用额外空间,所以空间复杂度为O(1)。

综上所述,数独解法的总体空间复杂度为O(1),时间复杂度为O(81)。

LeetCode运行结果:

方法二:枚举优化

class Solution {
    private int[] line = new int[9];
    private int[] column = new int[9];
    private int[][] block = new int[3][3];
    private boolean valid = false;
    private List<int[]> spaces = new ArrayList<int[]>();

    public void solveSudoku(char[][] board) {
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] != '.') {
                    int digit = board[i][j] - '0' - 1;
                    flip(i, j, digit);
                }
            }
        }

        while (true) {
            boolean modified = false;
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    if (board[i][j] == '.') {
                        int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
                        if ((mask & (mask - 1)) == 0) {
                            int digit = Integer.bitCount(mask - 1);
                            flip(i, j, digit);
                            board[i][j] = (char) (digit + '0' + 1);
                            modified = true;
                        }
                    }
                }
            }
            if (!modified) {
                break;
            }
        }

        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    spaces.add(new int[]{i, j});
                }
            }
        }

        dfs(board, 0);
    }

    public void dfs(char[][] board, int pos) {
        if (pos == spaces.size()) {
            valid = true;
            return;
        }

        int[] space = spaces.get(pos);
        int i = space[0], j = space[1];
        int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
        for (; mask != 0 && !valid; mask &= (mask - 1)) {
            int digitMask = mask & (-mask);
            int digit = Integer.bitCount(digitMask - 1);
            flip(i, j, digit);
            board[i][j] = (char) (digit + '0' + 1);
            dfs(board, pos + 1);
            flip(i, j, digit);
        }
    }

    public void flip(int i, int j, int digit) {
        line[i] ^= (1 << digit);
        column[j] ^= (1 << digit);
        block[i / 3][j / 3] ^= (1 << digit);
    }
}

这段代码使用了位运算和深度优先搜索来解决数独问题。下面是算法的思路:

  1. 初始化 linecolumn 和 block 数组,用于记录每行、每列和每个九宫格中已经出现的数字状态。
  2. 遍历整个数独棋盘,对于已填入数字的格子,更新相应的状态数组。
  3. 使用循环,不断尝试填入数字,直到无法再填入为止。在每次循环中,遍历棋盘上的每个空白格子,并计算可填入数字的条件:
    • 通过位运算计算出当前格子可用的数字(即未出现在同一行、同一列和同一个九宫格中的数字)。
    • 如果仅有一个数字满足条件,则将其填入,并更新状态数组。
    • 如果有多个数字满足条件,则跳过该格子,继续下一个格子。
  4. 遍历完成后,如果仍存在空白格子,将它们的位置保存在 spaces 列表中。
  5. 调用深度优先搜索函数 dfs,递归地尝试填入空白格子:
    • 如果已经填完所有空白格子,设定 valid 为真并返回。
    • 取出下一个空白格子的位置,计算可填入的数字的条件。
    • 通过位运算,逐个尝试可填入的数字,并进行递归搜索。
  6. 如果搜索到最后,仍未找到合法解,则将之前填入的数字恢复,并返回上一层继续搜索其他可能的数字组合。

这种解法通过位运算和状态压缩技巧,提高了数独求解的效率。同时使用深度优先搜索来穷举所有可能的数字组合,直到找到合法解或遍历完所有空白格子。

复杂度分析:

时间复杂度:

  • 初始化部分需要遍历数独棋盘,时间复杂度为O(81) = O(1)。
  • 循环填入数字的部分,最坏情况下需要进行多轮循环,但每轮循环中每个格子的操作是常数时间的,因此可以认为整体时间复杂度为O(81) = O(1)。
  • 深度优先搜索部分,最坏情况下需要穷举所有可能的数字组合,并且每个格子都有9种选择,因此时间复杂度为O(9^(空白数量))。空白数量通常较小,因此可以近似看作常数,即O(1)。 综上所述,整体时间复杂度为O(1)。

空间复杂度:

  • 使用了line、column和block数组来记录数字出现的状态,每个数组的长度为9,因此空间复杂度为O(9) = O(1)。
  • 使用了spaces列表来保存空白格子的位置,最多有81个空白格子,因此空间复杂度为O(81) = O(1)。
  • 递归调用dfs函数时产生的函数调用栈空间,最多深度为空白数量,通常较小,因此空间复杂度为O(1)。 综上所述,整体空间复杂度为O(1)。

总结起来,该算法的时间复杂度和空间复杂度都是O(1),表示算法的运行时间和占用的额外空间都与输入规模无关,非常高效。

LeetCode运行结果:

第三题

题目来源

38. 外观数列 - 力扣(LeetCode)

题目内容

解决方法

方法一:递归

要解决这个问题,我们可以使用递归的方法来生成外观数列。首先,定义一个递归函数generateNext,该函数输入一个数字字符串,并返回对其进行描述后的新字符串。然后,我们可以使用递归调用generateNext来生成外观数列的第n项。

public class Solution {
    public String countAndSay(int n) {
        if (n == 1) {
            return "1";
        }
        
        String prev = countAndSay(n - 1);
        StringBuilder result = new StringBuilder();
        int count = 1;
        
        for (int i = 0; i < prev.length(); i++) {
            // 如果下一个字符与当前字符相同,则增加计数器
            if (i < prev.length() - 1 && prev.charAt(i) == prev.charAt(i + 1)) {
                count++;
            } else {  // 否则,将描述添加到结果中,并重置计数器
                result.append(count);
                result.append(prev.charAt(i));
                count = 1;
            }
        }
        
        return result.toString();
    }
}

在上面的代码中,当n为1时,直接返回"1";否则,先递归调用countAndSay(n - 1)来得到前一项的描述字符串,然后遍历该字符串,统计相邻相同字符的个数,并将个数和字符添加到结果中。最后,返回结果字符串。通过调用countAndSay函数,可以得到外观数列的第n项。

复杂度分析:

  • 时间复杂度分析:
  • 对于每一项n,我们需要递归调用`countAndSay(n - 1)`来得到前一项的描述字符串。因此,总共需要进行n次递归调用。
  • 在每一次递归调用中,我们需要遍历前一项的描述字符串,计算相邻相同字符的个数,并将结果添加到结果中。这一步的时间复杂度是O(len(prev)),其中len(prev)表示前一项描述字符串的长度。
  • 综上所述,总的时间复杂度是O(1 + 2 + 3 + ... + n) = O(n^2),其中n是给定的正整数。

空间复杂度分析:

  • 递归调用`countAndSay(n)`的最大深度是n,因此递归栈的空间复杂度是O(n)。
  • 此外,在每一次递归调用中,我们使用一个StringBuilder来构建当前项的描述字符串,并返回它。这个StringBuilder的空间也是O(n)。
  • 综上所述,总的空间复杂度是O(n)。

综合起来,该算法的时间复杂度是O(n^2),空间复杂度是O(n)。

LeetCode运行结果:

方法二:迭代

除了递归之外,我们还可以使用迭代的方法来生成外观数列。

public class Solution {
    public String countAndSay(int n) {
        String result = "1";
        
        for (int i = 2; i <= n; i++) {
            StringBuilder temp = new StringBuilder();
            int count = 1;
            
            for (int j = 0; j < result.length(); j++) {
                // 如果下一个字符与当前字符相同,则增加计数器
                if (j < result.length() - 1 && result.charAt(j) == result.charAt(j + 1)) {
                    count++;
                } else {  // 否则,将描述添加到临时字符串中,并重置计数器
                    temp.append(count);
                    temp.append(result.charAt(j));
                    count = 1;
                }
            }
            
            result = temp.toString();
        }
        
        return result;
    }
}

在上面的代码中,我们使用一个循环从2到n,依次生成外观数列的每一项。对于每一项,我们使用一个临时的StringBuilder来构建它的描述字符串,并更新result变量为临时字符串的值。

复杂度分析:

这种迭代方法的时间复杂度和空间复杂度与递归方法相同,都是O(n^2)和O(n),因为我们仍然需要遍历前一项的描述字符串来计算当前项的描述字符串。只是在实现上,迭代方法更简单直观,没有递归的函数调用开销。

LeetCode运行结果:

方法三:动态规划

除了递归和迭代,还可以使用动态规划的方法来生成外观数列。动态规划通过存储中间结果来避免重复计算,提高效率。

public class Solution {
    public String countAndSay(int n) {
        List<String> dp = new ArrayList<>();
        dp.add("1"); // 初始项
        
        for (int i = 1; i < n; i++) {
            String prev = dp.get(i - 1); // 前一项的描述字符串
            StringBuilder current = new StringBuilder();
            int count = 1;
            
            for (int j = 0; j < prev.length(); j++) {
                // 如果下一个字符与当前字符相同,则增加计数器
                if (j < prev.length() - 1 && prev.charAt(j) == prev.charAt(j + 1)) {
                    count++;
                } else {  // 否则,将描述添加到临时字符串中,并重置计数器
                    current.append(count);
                    current.append(prev.charAt(j));
                    count = 1;
                }
            }
            
            dp.add(current.toString()); // 将当前项的描述字符串添加到动态规划数组中
        }
        
        return dp.get(n - 1); // 返回第n项的描述字符串
    }
}

在上面的代码中,我们使用一个动态规划数组dp来存储每一项的描述字符串。初始时,将"1"作为第一项的描述字符串。然后,从2到n依次计算每一项的描述字符串,并将其存储到动态规划数组中。最后,返回第n项的描述字符串。

复杂度分析:

使用动态规划方法,我们将外观数列的每一项的描述字符串存储起来,避免了重复计算,提高了效率。它的时间复杂度仍然是O(n^2),但相对于递归和迭代方法,动态规划在计算过程中节省了一些中间计算的时间。空间复杂度为O(n),用来存储动态规划数组。

LeetCode运行结果:

方法四:递推

除了前面提到的方法,还可以使用递推方法来生成外观数列。递推方法是指根据已知的前几项,通过递推公式计算得到后续的项数。

public class Solution {
    public String countAndSay(int n) {
        String current = "1"; // 初始项
        
        for (int i = 1; i < n; i++) {
            StringBuilder next = new StringBuilder();
            int count = 1;
            char ch = current.charAt(0);
            
            for (int j = 1; j < current.length(); j++) {
                // 如果下一个字符与当前字符相同,则增加计数器
                if (current.charAt(j) == ch) {
                    count++;
                } else { // 否则,将计数器和当前字符追加到下一个描述字符串中,并更新当前字符和计数器
                    next.append(count).append(ch);
                    ch = current.charAt(j);
                    count = 1;
                }
            }
            
            next.append(count).append(ch); // 将最后一个连续数字段追加到下一个描述字符串中
            current = next.toString(); // 更新当前描述字符串为下一个描述字符串
        }
        
        return current; // 返回第n项的描述字符串
    }
}

在这种方法中,我们根据外观数列的定义,通过递推公式计算每一项的描述字符串。具体来说,我们遍历当前项的描述字符串,记录当前字符和计数器。如果下一个字符与当前字符相同,则增加计数器;否则,将计数器和当前字符追加到下一个描述字符串中,并更新当前字符和计数器。最后,将最后一个连续数字段追加到下一个描述字符串中,更新当前描述字符串为下一个描述字符串。通过这种方式,我们可以递推得到所有项的描述字符串。

复杂度分析:

  • 使用递推方法,我们避免了使用递归或动态规划来求解外观数列,减少了时间和空间复杂度。但是,递推方法需要根据递推公式,对每一项进行计算,因此时间复杂度仍然为O(n^2)。
  • 空间复杂度为O(m),其中m是当前项的长度。在每次计算下一项时,我们只需使用一个StringBuilder对象来构建描述字符串,其长度为m。每次计算完成后,我们无需保留之前的计算结果,因此只需要恒定的额外空间来存储当前项的描述字符串。因此,总的空间复杂度为O(m)。

LeetCode运行结果:

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

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

相关文章

Unity之NetCode多人网络游戏联机对战教程(3)--NetworkObject组件讲解

文章目录 NetworkObjectAlways Replicate As RootSynchronization TransformActive Scene SynchronizationScene Migration SynchronizationSpawn With ObserversDont Destroy With OwnerAuto Object Parent Sync 后话 NetworkObject 为了复制任何Netcode感知属性或发送/接收R…

Linux生产者和消费者模型 条件变量 信号量

/*条件变量类型 pthread_cond_tint pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);int pthread_cond_destory(pthread_cond_t * cond);int pthread_cond_wait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict …

人生第一个java项目 学生管理系统

开始编程 建类 开始主要部分 main()部分 方法部分

Nodejs+vue高校机房设备管理系统jt07u

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 集成IDE对高校机房设备管理系统统进行开发,整合系统的各个模块。 拟开发的高校机房设备管理系统通过测试,确保在最大负载的情况下…

新型crypt勒索病毒,都有哪些特征?勒索病毒解密,数据恢复

近日&#xff0c;云天数据恢复中心在接受用户咨询的过程中发现&#xff0c;市场上悄然出现了一种新型的勒索病毒——crypt勒索病毒&#xff0c;接下来我们将这种类型的勒索病毒做一个全面的分析。 一&#xff0c;中了crypt勒索病毒的特征 在桌面以及多个文件夹中都有一个名称为…

matlab产生指定功率的噪声信号、固定SNR的信号

randn函数产生噪声信号 首先要理解信号的幅度和功率&#xff0c;例如信号的幅度为 U U U&#xff0c;那么信号的功率就是 U 2 U^2 U2&#xff0c;他们之间是平方的关系。 matlab中randn函数用法&#xff0c;产生正态分布的随机数或矩阵的函数。 randn&#xff1a;产生均值为0…

基于Java+vue开发的企事业移动培训考试平台

随着移动互联网的快速发展&#xff0c;越来越多的企业开始关注移动培训和考试平台的开发。为了满足这一需求&#xff0c;我们可以使用Java和Vue来开发一个基于移动端的企事业培训考试平台。 一、背景和需求 企事业移动培训考试平台是一个基于Web的应用程序&#xff0c;旨在提…

el-upload上传文件(vue2,Element中的 el-upload文件上传)

简介&#xff1a;el-upload是一个基于Element UI的上传组件&#xff0c;大家应该都知道&#xff0c;它可以方便地实现文件上传功能&#xff0c;今天来记录下如何&#xff08;在vue2中&#xff09;使用el-upload上传文件。 1、首先&#xff0c;我们想要使用el-upload&#xff0c…

Redux Toolkit中action派发但state值不更新的原因

最近一个react项目使用了Redux Toolkit&#xff0c;但是遇到了一个问题&#xff1a;数组始终返回为null&#xff0c;读取不到length. 这个只是问题的表象&#xff0c;真正的原因是productList数据没能从redux中结构出来 但是postman请求是由数据返回的&#xff1a; 推断&#x…

openMVS编译

参考官方文档&#xff1a;https://github.com/cdcseacave/openMVS/wiki/Building vcglib的安装 cd /home/juling/lib git clone -b v1.0.1 https://github.com/cdcseacave/VCG.git vcglibgit clone --recurse-submodules https://github.com/cdcseacave/openMVS.git cd openMV…

git代码管理(一)

目录 介绍暂存区安装创建仓库提交文件查看当前是否还有文件未提交查看提交历史版本回退恢复版本回退 介绍 git是一个分布式的代码版本管理工具&#xff08;区别于集中式管理的svn&#xff09;&#xff0c;分布式的意思是对于同一个项目可以有多个仓库存储&#xff0c;分布在不…

服务器(Windows系统)自建filebrowser网盘服务器超详细教程

需要依赖&#xff08;工具&#xff09; 轻量服务器&#xff08;云服务器&#xff09;一台 —— 环境Windows Server 2019filebrowser安装包&#xff08;https://github.com/filebrowser/filebrowser/releases&#xff09; 下载安装filebrowser 进入链接下载&#xff1a;https:/…

基于OpenSceneGraph的三维模型格式转换(以OBJ为例),并简化、输出纹理图片到指定目录(附完整C++代码和exe)

文章目录 前言一、OpenSceneGraph库1. OSG源码2. 编译教程2. Windows编译完成版 二、osgconv格式转换工具1. osgconv官方说明文档2. osgconv工具调用 三、基于C格式转换&#xff0c;简化OBJ&#xff0c;输出纹理到指定目录1. 项目环境2. 完整代码3. 可执行文件 前言 本文基于O…

记录:移动设备软件开发(Activity的显式启动和隐式启动)

目录 Intent对象简述Intent的作用Intent开启Activtiy显式启动Activity隐式启动Activity Intent对象简述 Android的应用程序包含三种重要组件&#xff1a;Activity、Service、BroadcastReceiver&#xff0c;应用程序采用了一致的方式来启动它们——都是依靠Intent来启动的&…

flv怎么转换成mp4格式?准备3个方法给大家

flv怎么转换成mp4格式&#xff1f;FLV是一种流行的视频文件格式&#xff0c;最初由Adobe公司开发&#xff0c;用于在Web上播放和传输视频内容。FLV格式以其较小的文件大小和较高的压缩比而闻名&#xff0c;并广泛应用于在线视频分享平台、流媒体服务和网络广告等领域。能够提供…

c++图像的边缘检测

图像的边缘检测 cv::Canny 是 OpenCV 中用于进行边缘检测的函数&#xff0c;特别是用于检测图像中的边缘。Canny 边缘检测是一种广泛使用的技术&#xff0c;它能够识别图像中的边缘&#xff0c;这些边缘通常表示对象之间的边界或图像中的显著特征 void cv::Canny(const cv::M…

linux 查看CPU架构是AMD还是ARM

要查看 Linux 系统的 CPU 架构是 AMD 还是 ARM&#xff0c;可以使用以下命令&#xff1a; 使用 lscpu 命令并查找 Architecture 字段&#xff1a; lscpu | grep Architecture如果输出结果中包含 x86_64 或 i686&#xff0c;则表示系统的 CPU 架构是 AMD&#xff08;或者是 x86…

地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许

地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许 地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许

Python中的用法与常见问题解析

装饰器是Python语言中一种强大且常用的概念。通过装饰器&#xff0c;我们可以在不修改原始函数代码的情况下&#xff0c;给函数添加额外的功能&#xff0c;比如日志记录、性能分析、输入验证等。在本文中&#xff0c;我们将深入探讨Python中装饰器的用法和常见问题&#xff0c;…

接口自动化测试:pytest基础讲解

为什么要做接⼝测试&#xff1f; 只靠前端测试很难确保很⾼的覆盖率。接⼝测试&#xff0c;可以模拟出各种类型的⼊参&#xff0c;包括⼀些在前端模拟不出来的⼊参&#xff0c;还能根据接⼝⽂档的定义&#xff0c;设计出相对完善的⼊参值&#xff0c;在接⼝层保证质量&#xff…