怒刷LeetCode的第14天(Java版)

目录

第一题

题目来源

题目内容

解决方法

方法一:动态规划

方法二:栈

方法三:双指针

第二题

题目来源

题目内容

解决方法

方法一:二分查找

方法二:线性扫描

方法三:递归

第三题

题目来源

题目内容

解决方法

方法一:二分查找

方法二:线性扫描

方法三:双指针


第一题

题目来源

32. 最长有效括号 - 力扣(LeetCode)

题目内容

解决方法

方法一:动态规划

  1. 创建一个长度为 n 的数组 dp,用于保存以当前字符结尾的最长有效括号子串的长度。
  2. 初始化 dp 数组的所有元素为 0。
  3. 遍历字符串 s 的每个字符:
    • 如果当前字符是 (,则直接跳过。
    • 如果当前字符是 ),则判断前一个字符是否是 (
      • 如果前一个字符是 (,则更新 dp[i] = dp[i-2] + 2,表示以当前字符结尾的最长有效括号子串长度为前一个字符结尾的最长有效括号子串长度加上当前的两个括号。
      • 如果前一个字符是 ),则判断前一个字符结尾的最长有效括号子串之前的字符是否是 (,即判断 i-dp[i-1]-1 位置的字符是否是 (
        • 如果是 (,则更新 dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2,表示以当前字符结尾的最长有效括号子串长度为前一个字符结尾的最长有效括号子串长度加上前一个字符结尾的最长有效括号子串之前的最长有效括号子串长度加上当前的两个括号。
  4. 遍历完整个字符串后,找出 dp 数组中的最大值,即为最长有效括号子串的长度。
public class Solution {public int longestValidParentheses(String s) {if (s == null || s.length() == 0) {return 0;}int n = s.length();int[] dp = new int[n];int maxLen = 0;for (int i = 1; i < n; i++) {if (s.charAt(i) == ')') {if (s.charAt(i - 1) == '(') {dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;} else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;}maxLen = Math.max(maxLen, dp[i]);}}return maxLen;}
}

复杂度分析:

时间复杂度:

  • 遍历字符串 s 的每个字符需要 O(n) 的时间。
  • 在每个字符上,我们都进行了常数次的比较和更新操作。
  • 因此,总体上,时间复杂度为 O(n)。

空间复杂度:

  • 我们使用了一个长度为 n 的数组 dp 来保存以当前字符结尾的最长有效括号子串的长度。
  • 因此,空间复杂度为 O(n)。

综合起来,该解法的时间复杂度为 O(n),空间复杂度为 O(n)。

注意:对于这个特定的问题,在给定的限制条件下(0 <= s.length <= 3 * 10^4),这个解法是高效且可行的。

LeetCode运行结果:

方法二:栈

该方法的思路如下:

  • 首先,我们使用一个栈来保存括号的索引位置。
  • 初始化栈,将一个特殊的值 -1 放入栈中。
  • 遍历字符串 s 的每个字符:
    • 如果遇到左括号 (,将其索引位置压入栈中。
    • 如果遇到右括号 ),弹出栈顶元素,表示当前右括号匹配了一个左括号。
      • 如果栈为空,将当前右括号的索引位置压入栈中,作为一个新的起点。
      • 如果栈不为空,计算当前有效括号子串的长度,更新最大长度。
  • 最后,返回最大长度即可。
import java.util.Stack;public class Solution {public int longestValidParentheses(String s) {if (s == null || s.length() == 0) {return 0;}int maxLen = 0;Stack<Integer> stack = new Stack<>();stack.push(-1);for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(i);} else {stack.pop();if (stack.isEmpty()) {stack.push(i);} else {maxLen = Math.max(maxLen, i - stack.peek());}}}return maxLen;}
}

复杂度分析:

时间复杂度:

  • 遍历字符串 s 的每个字符需要 O(n) 的时间。
  • 在每个字符上,我们进行了常数次的栈操作(压栈和弹栈)。
  • 因此,总体上,时间复杂度为 O(n)。

空间复杂度:

  • 我们使用了一个栈来保存括号的索引位置。
  • 在最坏情况下,当所有字符都是左括号时,栈的大小为 n。
  • 因此,空间复杂度为 O(n)。

综合起来,该方法的时间复杂度为 O(n),空间复杂度为 O(n)。

LeetCode运行结果:

方法三:双指针

除了动态规划和栈,还有一种双指针的方法来解决最长有效括号问题。

这种方法的思路如下:

  • 从左到右遍历字符串,统计左右括号的数量。
  • 如果左右括号数量相等,则更新最大长度。
  • 如果右括号数量大于左括号数量,则重置左右括号数量为0。
  • 然后从右到左再进行一次相同的操作。
public class Solution {public int longestValidParentheses(String s) {if (s == null || s.length() == 0) {return 0;}int left = 0; // 左括号数量int right = 0; // 右括号数量int maxLen = 0; // 最大长度// 从左到右遍历for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {left++;} else {right++;}// 如果左括号数量等于右括号数量,则计算当前有效括号子串的长度if (left == right) {maxLen = Math.max(maxLen, right * 2);} else if (right > left) { // 右括号数量大于左括号数量,重置左右括号数量为0left = 0;right = 0;}}left = 0;right = 0;// 从右到左遍历for (int i = s.length() - 1; i >= 0; i--) {char c = s.charAt(i);if (c == ')') {right++;} else {left++;}// 如果左括号数量等于右括号数量,则计算当前有效括号子串的长度if (left == right) {maxLen = Math.max(maxLen, left * 2);} else if (left > right) { // 左括号数量大于右括号数量,重置左右括号数量为0left = 0;right = 0;}}return maxLen;}
}

复杂度分析:

时间复杂度:

  • 遍历字符串 s 的每个字符需要 O(n) 的时间。
  • 在第一次从左到右遍历中,我们进行了常数次的操作,不会产生额外的时间复杂度。
  • 在第二次从右到左遍历中,同样也进行了常数次的操作。
  • 因此,总体上,时间复杂度为 O(n)。

空间复杂度:

  • 我们只使用了常数个变量来保存左右括号的数量和最大长度,没有使用额外的数据结构。
  • 因此,空间复杂度为 O(1)。

综合起来,该方法的时间复杂度为 O(n),空间复杂度为 O(1)。

LeetCode运行结果:

第二题

题目来源

33. 搜索旋转排序数组 - 力扣(LeetCode)

题目内容

解决方法

方法一:二分查找

使用二分查找的思想,通过判断左右半边哪一边是有序的来决定向哪边继续查找。具体步骤如下:

  1. 初始化左指针 left 为数组的第一个元素的索引,右指针 right 为数组最后一个元素的索引。
  2. 在每次循环中,计算中间元素的索引 mid
  3. 如果中间元素等于目标值,则返回 mid
  4. 判断左半边是否有序(即 nums[left] <= nums[mid]):
    • 如果目标值在左半边的有序范围内,则将右指针 right 移动到 mid - 1,继续在左半边查找。
    • 否则,将左指针 left 移动到 mid + 1,继续在右半边查找。
  5. 如果左半边不是有序的,则右半边一定是有序的。判断目标值是否在右半边的有序范围内:
    • 如果是,则将左指针 left 移动到 mid + 1,继续在右半边查找。
    • 否则,将右指针 right 移动到 mid - 1,继续在左半边查找。
  6. 如果循环结束仍未找到目标值,则返回 -1。
public class Solution {public int search(int[] nums, int target) {if (nums == null || nums.length == 0) {return -1;}int left = 0;int right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] == target) {return mid;}if (nums[left] <= nums[mid]) { // 左半边有序if (target >= nums[left] && target < nums[mid]) {right = mid - 1;} else {left = mid + 1;}} else { // 右半边有序if (target > nums[mid] && target <= nums[right]) {left = mid + 1;} else {right = mid - 1;}}}return -1;}
}

复杂度分析:

  • 该算法的时间复杂度为O(log n),其中n是数组的长度。在每次循环中,都将搜索范围缩小一半,所以总共最多需要进行log n次循环。因此,算法的时间复杂度为O(log n)。
  • 空间复杂度为O(1),因为算法只使用了有限的额外空间来存储指针和常量。

总结起来,该算法具有较低的时间复杂度和空间复杂度,能够高效地解决搜索旋转排序数组的问题。

LeetCode运行结果:

方法二:线性扫描

除了二分查找的方法,还可以使用线性扫描的方法来搜索旋转排序数组。

该算法从数组的第一个元素开始,依次遍历数组中的每个元素,如果找到目标值,则返回其索引;如果遍历结束仍未找到目标值,则返回-1。

public class Solution {public int search(int[] nums, int target) {if (nums == null || nums.length == 0) {return -1;}for (int i = 0; i < nums.length; i++) {if (nums[i] == target) {return i;}}return -1;}
}

复杂度分析:

  • 线性扫描算法的时间复杂度为O(n),其中n是数组的长度。算法需要遍历整个数组来查找目标值,因此最坏情况下需要执行n次比较操作。
  • 空间复杂度为O(1),因为算法没有使用额外的空间,只需常数级别的额外空间。

相对于二分查找算法的O(log n)时间复杂度,线性扫描算法的时间复杂度较高。但在某些特定场景或者输入规模较小的情况下,线性扫描算法也可以快速解决问题。

综上所述,线性扫描算法适用于简单的问题或者规模较小的数据集,但在更大规模的数据集上,二分查找算法通常更具优势。

LeetCode运行结果:

方法三:递归

除了二分查找和线性扫描的方法,还可以使用递归的方法来搜索旋转排序数组。

该算法与二分查找算法类似,也是通过判断左右半边哪一边是有序的来决定向哪边继续查找。不同之处在于,该算法使用递归的方式实现,将数组的搜索范围不断缩小。

  1. 算法首先检查数组是否为空或者长度为0,如果是,则返回-1。然后调用递归函数 search 进行搜索,传入参数 nums 数组、目标值 target、搜索范围的左右端点索引 left 和 right。
  2. 在递归函数中,首先判断搜索范围是否合法,如果不合法,则返回-1。然后计算中间元素索引 mid。如果中间元素等于目标值,则返回 mid。
  3. 接着判断左半边是否有序(即 nums[left] <= nums[mid])。如果是,则判断目标值是否在左半边的有序范围内。如果是,则继续在左半边递归查找;否则,在右半边递归查找。
  4. 如果左半边不是有序的,则右半边一定是有序的。判断目标值是否在右半边的有序范围内。如果是,则在右半边递归查找;否则,在左半边递归查找。
  5. 最后,如果循环结束仍未找到目标值,则返回-1。
public class Solution {public int search(int[] nums, int target) {if (nums == null || nums.length == 0) {return -1;}return search(nums, target, 0, nums.length - 1);}private int search(int[] nums, int target, int left, int right) {if (left > right) {return -1;}int mid = left + (right - left) / 2;if (nums[mid] == target) {return mid;}if (nums[left] <= nums[mid]) { // 左半边有序if (target >= nums[left] && target < nums[mid]) {return search(nums, target, left, mid - 1);} else {return search(nums, target, mid + 1, right);}} else { // 右半边有序if (target > nums[mid] && target <= nums[right]) {return search(nums, target, mid + 1, right);} else {return search(nums, target, left, mid - 1);}}}
}

复杂度分析:

时间复杂度:

  • 最好情况下,数组是完全有序的,每次都能通过比较找到目标值,时间复杂度为 O(log n)。
  • 最坏情况下,每次都只能排除一个元素,需要遍历整个数组,时间复杂度为 O(n)。
  • 平均情况下,假设数组中大致一半是有序的,一半是无序的,时间复杂度介于 O(log n) 和 O(n) 之间。

空间复杂度:

  • 每次递归调用会在栈上保存一些临时变量和返回地址,最大递归深度为 log n,因此空间复杂度为 O(log n)。

综合考虑,递归搜索旋转排序数组的算法在最坏情况下的时间复杂度为 O(n),空间复杂度为 O(log n)。但如果数组是近似有序的或者目标值位于有序部分内,时间复杂度可以接近 O(log n),效率较高。

需要注意的是,递归算法和二分查找算法类似,但由于需要额外的栈空间,因此可能会更慢。在处理超大规模数据时,可能会导致栈溢出问题。

LeetCode运行结果:

第三题

题目来源

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

题目内容

解决方法

方法一:二分查找

  1. 首先,我们定义一个长度为2的整数数组 result,并初始化为 {-1, -1}。这个数组表示目标值的开始位置和结束位置。
  2. 然后,我们使用两个辅助函数 findLeft 和 findRight 来分别查找目标值的开始位置和结束位置。
  3. 在 findLeft 函数中,我们使用二分查找来搜索目标值的开始位置。初始时,左边界 left 指向数组的第一个元素,右边界 right 指向数组的最后一个元素。在每次循环中,计算中间元素索引 mid,并将它与目标值进行比较。如果中间元素大于或等于目标值,则将右边界 right 缩小为 mid;否则,将左边界 left 扩大为 mid + 1。最后,返回 left 的值作为目标值的开始位置。如果目标值不存在,则返回 -1。
  4. 在 findRight 函数中,我们同样使用二分查找来搜索目标值的结束位置。不过这次的二分查找稍有不同。初始时,左边界 left 指向数组的第一个元素,右边界 right 指向数组的最后一个元素。在每次循环中,计算中间元素索引 mid,并将它与目标值进行比较。如果中间元素小于或等于目标值,则将左边界 left 扩大为 mid;否则,将右边界 right 缩小为 mid - 1。最后,返回 left 的值作为目标值的结束位置。如果目标值不存在,则返回 -1。
  5. 最后,在主函数 searchRange 中,我们首先判断特殊情况,即数组为空或长度为0的情况,直接返回初始化好的 result 数组。
  6. 然后,我们通过调用辅助函数 findLeft 和 findRight 分别得到目标值的开始位置和结束位置,并将它们存储在 result 数组中。
  7. 最后,返回 result 数组作为结果。
class Solution {public int[] searchRange(int[] nums, int target) {int[] result = {-1, -1};if (nums == null || nums.length == 0) {return result;}int leftIndex = findLeft(nums, target);int rightIndex = findRight(nums, target);if (leftIndex <= rightIndex) {result[0] = leftIndex;result[1] = rightIndex;}return result;}private int findLeft(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] >= target) {right = mid;} else {left = mid + 1;}}return nums[left] == target ? left : -1;}private int findRight(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2 + 1;if (nums[mid] <= target) {left = mid;} else {right = mid - 1;}}return nums[left] == target ? left : -1;}
}

复杂度分析:

  • 时间复杂度:O(log n)。每次迭代都将搜索空间减半,因此时间复杂度为对数级别。
  • 空间复杂度:O(1)。仅使用了有限的额外空间来存储几个变量。

LeetCode运行结果:

方法二:线性扫描

除了二分查找,还可以使用线性扫描的方法来搜索排序数组中目标值的开始位置和结束位置。

  1. 我们首先遍历整个数组来查找目标值的开始位置。如果找到目标值,我们将其索引存储在 result[0] 中并立即退出循环。如果没有找到目标值,则 result[0] 保持为初始值 -1。
  2. 接着,我们再从数组的末尾开始向前遍历,查找目标值的结束位置。如果找到目标值,我们将其索引存储在 result[1] 中并立即退出循环。如果没有找到目标值,则 result[1] 保持为初始值 -1。
  3. 最后,我们返回存储了目标值开始位置和结束位置的 result 数组。
class Solution {public int[] searchRange(int[] nums, int target) {int[] result = {-1, -1};if (nums == null || nums.length == 0) {return result;}for (int i = 0; i < nums.length; i++) {if (nums[i] == target) {result[0] = i;break;}}if (result[0] != -1) {for (int j = nums.length - 1; j >= 0; j--) {if (nums[j] == target) {result[1] = j;break;}}}return result;}
}

复杂度分析:

  • 时间复杂度:O(n)。需要遍历整个数组,其中 n 是数组的长度。
  • 空间复杂度:O(1)。仅使用了有限的额外空间来存储几个变量。

因为二分查找的时间复杂度为 log n,而线性扫描的时间复杂度为 n,所以在数组较大且已排序的情况下,二分查找的性能更好。它减少了搜索空间的大小,使得平均查找次数更低。然而,在数组较小或未排序的情况下,线性扫描是一种简单有效的方法。

LeetCode运行结果:

方法三:双指针

除了二分查找和线性扫描,还有一种常用的方法是双指针法。这种方法适用于有序数组或部分有序数组,并且可以在 O(n) 的时间复杂度内找到目标值的开始位置和结束位置。

class Solution {public int[] searchRange(int[] nums, int target) {int[] result = {-1, -1};if (nums == null || nums.length == 0) {return result;}int left = 0;int right = nums.length - 1;// 查找目标值的开始位置while (left <= right) {if (nums[left] == target && nums[right] == target) {result[0] = left;result[1] = right;break;}if (nums[left] < target) {left++;}if (nums[right] > target) {right--;}}return result;}
}

在上述代码中,我们使用两个指针 left 和 right 来标记搜索区间。通过不断更新指针的位置,我们可以确定目标值的开始位置和结束位置。

具体步骤如下:

  1. 初始化指针 left 和 right 分别指向数组的首尾元素。
  2. 当 left 指向的元素小于目标值时,将 left 向右移动一位。
  3. 当 right 指向的元素大于目标值时,将 right 向左移动一位。
  4. 如果 left 和 right 指向的元素都等于目标值,则找到了目标值的开始位置和结束位置。将结果存储在 result 数组中,并退出循环。
  5. 如果找不到目标值,则返回初始值为 -1 的 result 数组。

复杂度分析:

  • 使用双指针法的时间复杂度是 O(n),其中 n 是数组的长度。在最坏的情况下,即目标值不在数组中或者目标值在数组中出现了 n 次,我们需要将指针 left 和 right 分别移动到数组的两端。因此,最多需要遍历整个数组一次,时间复杂度为 O(n)。
  • 空间复杂度是 O(1),因为我们只需要使用有限的额外变量来记录指针的位置和存储结果数组。

需要注意的是,双指针法适用于有序数组或部分有序数组,如果数组无序,则双指针法无法正确找到目标值的开始位置和结束位置。

LeetCode运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度解析React 18应用性能提升

众所周知,React 18 引入的一个重要特性就是并发功能,从根本上改变了 React 应用程序的渲染方式。本文将带大家一同探讨这些最新功能的具体作用,特别是如何提高应用程序性能。 一、主线程与长任务 当我们在浏览器中运行 JavaScript 时,JS 引擎会在单线程环境下执行代码内容…

2、RocketMQ消息的分类

一、普通消息 1 消息发送分类 Producer对于消息的发送方式也有多种选择&#xff0c;不同的方式会产生不同的系统效果。 同步发送消息 同步发送消息是指&#xff0c;Producer发出⼀条消息后&#xff0c;会在收到MQ返回的ACK之后才发下⼀条消息。该方式的消息可靠性最高&#xff…

Python 运行代码

一、Python运行代码 可以使用三种方式运行Python&#xff0c;如下&#xff1a; 1、交互式 通过命令行窗口进入 Python 并开始在交互式解释器中开始编写 Python 代码 2、命令行脚本 可以把代码放到文件中&#xff0c;通过python 文件名.py命令执行代码&#xff0c;如下&#xff…

Android进阶之路 - 盈利、亏损金额格式化

在金融类型的app中&#xff0c;关于金额、数字都相对敏感和常见一些&#xff0c;在此仅记录我在金融行业期间学到的皮毛&#xff0c;如后续遇到新的场景也会加入该篇 该篇大多采用 Kotlin 扩展函数的方式进行记录&#xff0c;尽可能熟悉 Kotlin 基础知识 兄弟 Blog StringUti…

趣解设计模式之《小王的糖果售卖机》

〇、小故事 小王最近一直在寻找商机&#xff0c;他发现商场儿童乐园或者中小学校周围&#xff0c;会有很多小朋友喜欢吃糖果&#xff0c;那么他想设计一款糖果售卖机&#xff0c;让后将这些糖果售卖机布置到商场和学校旁边&#xff0c;这样就能获得源源不断的收益了。 想到这里…

并查集题目

并查集是一种十分常用并且好用的数据结构 并查集可以动态维护若干个不重叠的集合&#xff0c;支持合并与查询操作&#xff0c;是一种树形的数据结构 并查集的基础应用 村村通 对于这道题我们只需要求连通块的数量&#xff0c;然后将这几个联通快看成点&#xff0c;我们可以知…

【华为云云耀云服务器L实例评测|云原生】自定制轻量化表单Docker快速部署云耀云服务器

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

笔记2.2:网络应用基本原理

一. 网络应用的体系结构 &#xff08;1&#xff09;客户机/服务器结构&#xff08;Client-Server, C/S&#xff09; &#xff08;2&#xff09;点对点结构&#xff08;Peer-to-Peer&#xff0c;P2P&#xff09; &#xff08;3&#xff09;混合结构&#xff08;Hybrid&#x…

大数据学习技术栈及书籍推荐

作为一名开发人员&#xff0c;特别是后端开发人员&#xff0c;随着网络数据量的持续增长&#xff0c;拥有强大的大数据处理能力已经成为每个公司或产品&#xff08;尤其是2C业务&#xff09;的必备条件。以下是我在网络上搜集和自身研究的基础上&#xff0c;为您推荐的技术栈和…

【python】Seaborn画热力图,只显示第一行数字---seaborn与matplotlib版本问题

github上有这个讨论&#xff1a;Heatmap only has annotation text in the top row only Issue #3478 mwaskom/seaborn (github.com)翻译过来就是&#xff1a;热图仅在最上面一行有注释文本&#xff1b; 原因就是matplotlib 在2023年9月更新到了 3.8.0版本&#xff0c;改变了…

大数据Flink(八十三):SQL语法的DML:With、SELECT WHERE、SELECT DISTINCT 子句

文章目录 SQL语法的DML:With、SELECT & WHERE、SELECT DISTINCT 子句 一、DML:With 子句

c语言 static

1、静态局部变量在程序加载时初始化&#xff0c;静态局部变量的初始值写入到了data段&#xff1a; 如下代码test_symbol.c int f() {static int x 0;return x; }int g() {static int x 9;return x; }使用命令gcc -c test_symbol.c -o test_symbol 编译 使用命令 readelf -a …

Web ui自动化测试框架总结

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; 实施过了web系统的UI自动化&#xff0c;回顾梳理下&#xff0c;想到什么写什么&#xff0c;随时补充。 首…

数据分享|R语言逻辑回归、线性判别分析LDA、GAM、MARS、KNN、QDA、决策树、随机森林、SVM分类葡萄酒交叉验证ROC...

全文链接:http://tecdat.cn/?p27384 在本文中&#xff0c;数据包含有关葡萄牙“Vinho Verde”葡萄酒的信息&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 介绍 该数据集&#xff08;查看文末了解数据获取方式&#xff09;有1599个观测值和12个变量&#xf…

windows安装c环境

一. 下载安装mingw-w64 mingw-w64 解压后放到window环境变量路径 sysdm.cpl参看是否安装成功 二. 安装c idea Dev-Cpp下载及安装 新建文件 运行 编译&#xff08;F9&#xff09;、运行&#xff08;F10&#xff09;以及编译运行&#xff08;F11&#xff09; 参考 安装C…

Guava Cache介绍-面试用

一、Guava Cache简介 1、简介 Guava Cache是本地缓存&#xff0c;数据读写都在一个进程内&#xff0c;相对于分布式缓存redis&#xff0c;不需要网络传输的过程&#xff0c;访问速度很快&#xff0c;同时也受到 JVM 内存的制约&#xff0c;无法在数据量较多的场景下使用。 基…

图像处理之频域滤波DFT

摘要&#xff1a;傅里叶变换可以将任何满足相应数学条件的信号转换为不同系数的简单正弦和余弦函数的和。图像信号也是一种信号&#xff0c;只不过是二维离散信号&#xff0c;通过傅里叶变换对图像进行变换可以图像存空域转换为频域进行更多的处理。本文主要简要描述傅里叶变换…

Spring面试题11:什么是Spring的依赖注入

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的依赖注入 依赖注入(Dependency Injection)是Spring框架的一个核心特性,它是指通过外部容器将对象的依赖关系注入到对象中,从而…

win10 关闭edge跳转IE浏览器

按下windows键&#xff0c;搜索控制面板 右上角输入IE 点击IE 高级中取消下红框选择即可

接口自动化测试之Requests模块详解

Python中&#xff0c;系统自带的urllib和urllib2都提供了功能强大的HTTP支持&#xff0c;但是API接口确实太难用了。Requests 作为更高一层的封装&#xff0c;在大部分情况下对得起它的slogan——HTTP for Humans。 让我们一起来看看 Requests 这个 HTTP库在我们接口自动化测试…