学习刷题-12

3.22

hw机试【双指针】

Leetcode674 最长连续递增序列

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

双指针

  1. 一个慢指针一个快指针

  2. 慢指针记录递增子序列起点,快指针去寻找还在当前递增子序列的最后一个数

 class Solution {
     public int findLengthOfLCIS(int[] nums) {
         if(nums.length == 1) return 1;
         int slow = 0;
         int maxDeep = 0;
         int tempDeep = 1;
         for(int fast = 1; fast < nums.length; fast++){
             if(nums[fast] > nums[fast - 1]){
                 tempDeep++;
             }else{
                 slow = fast;
                 tempDeep = 1;
             }
             maxDeep = Math.max(maxDeep,tempDeep);
         }
         return maxDeep;
     }
 }
 class Solution {
     public int findLengthOfLCIS(int[] nums) {
         int ans = 0;
         int n = nums.length;
         int start = 0;
         for (int i = 0; i < n; i++) {
             if (i > 0 && nums[i] <= nums[i - 1]) {
                 start = i;
             }
             ans = Math.max(ans, i - start + 1);
         }
         return ans;
     }
 }
NC17 最长回文子串

最长回文子串牛客题霸牛客网 (nowcoder.com)

对于长度为n的一个字符串A(仅包含数字,大小写英文字母),请设计一个高效算法,计算其中最长回文子串的长度。

输入:"ababc"

返回值:3

说明:最长的回文子串为"aba"与"bab",长度都为3

贪心
  • step 1:遍历字符串每个字符。

  • step 2:以每次遍历到的字符为中心(分奇数长度和偶数长度两种情况),不断向两边扩展。

  • step 3:如果两边都是相同的就是回文,不断扩大到最大长度即是以这个字符(或偶数两个)为中心的最长回文子串。

  • step 4:我们比较完每个字符为中心的最长回文子串,取最大值即可。

import java.util.*;
 ​
 public class Solution {
     // 获取最长回文子串的方法
     public int getLongestPalindrome(String A) {
         // 初始最长回文子串长度为1,因为任何单个字符都是回文串
         int max = 1;
         // 遍历字符串,查找以当前字符为中心的回文子串
         for (int i = 0; i < A.length() - 1; i++) {
             // 更新最长回文子串长度,分别以当前字符及相邻字符为中心查找
             max = Math.max(max, Math.max(getNum(A, i, i), getNum(A, i, i + 1)));
         }
         return max;
     }
 ​
     // 查找以指定位置为中心的回文子串的长度
     private int getNum(String s, int start, int end) {
         // 从指定位置向两端扩展,直到不再构成回文串
         while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)) {
             start--; // 向左移动指针
             end++;   // 向右移动指针
         }
         // 返回回文子串的长度,注意要减去1,因为start和end之间的距离包含了回文子串本身
         return end - start - 1;
     }
 }
  • 时间复杂度:O n2

  • 空间复杂度:O 1,常数级变量,无额外辅助空间

动态规划

解题思路:

维护一个布尔型的二维数组dp,dp[i][j]表示 i 到 j 的子串是否是回文子串

每次先判断边界字符是否相等,再取决于上个状态的判断结果

算法流程:

  • 维护一个布尔型的二维数组dp,dp[i][j]表示 i 到 j 的子串是否是回文子串

  • 从长度0到字符串长度n进行判断

  • 选定起始下标 i 和终止下标 j, i 和 j 分别为要比较的字符串的左右边界指针

  • 从左右边界字符开始判断,即 A.charAt(i) == A.charAt(j)

    • 当相等时,还要判断当前长度 c 是否大于1,不大于则表明只有两个字符的字符串,一个或两个字符肯定是回文串,如“11”

    • 判断的长度大于1时,因为最左右的字符已经相等,因此取决于上一次的子串是否是回文子串, 如 “12121”

  • 更新回文串的最大长度

 import java.util.*;
 public class Solution {
     public int getLongestPalindrome(String A){
         // 初始化最长回文子串的长度为0
         int max = 0;
         // 获取字符串A的长度
         int n = A.length();
         // 创建一个二维布尔数组dp,用于记录字符串的某个子串是否为回文子串
         boolean[][] dp = new boolean[n][n];
         // 外层循环:遍历所有可能的子串长度
         for(int c = 0; c < n + 1; c++){
             // 内层循环:遍历字符串A,尝试找到所有长度为c的子串
             for(int i = 0; i < n - c; i++){
                 // 计算当前子串的结束索引
                 int j = i + c;
                 // 判断当前子串的首尾字符是否相等
                 if(A.charAt(i) == A.charAt(j)){
                     // 如果子串长度为1或2,并且首尾字符相等,则标记为回文子串
                     if(c <= 1){
                         dp[i][j] = true;
                     // 如果子串长度大于2,需要进一步判断去掉首尾字符后的子串是否为回文子串
                     }else{
                         dp[i][j] = dp[i+1][j-1];
                     }
                 }
                 // 如果当前子串被标记为回文子串,则更新最长回文子串的长度
                 if(dp[i][j]) max = c + 1;
             }
         }
         // 返回最长回文子串的长度
         return max;
     }
 }

想象一下,你有一串珍珠,每颗珍珠上都刻有一个字母,珍珠串代表给定的字符串。你的任务是找出这串珍珠中最长的那部分,使得从左边开始看和从右边开始看都是一样的顺序(即回文,如“level”或“radar”)。为了完成这个任务,你决定使用一个特殊的放大镜,这个放大镜可以覆盖珍珠串的任意一段,并且立即告诉你这一段是否是回文。

  1. 初始化:你决定使用一个表格(二维数组dp)来记录每一段珍珠(子串)是否是回文。表格的行和列代表珍珠串的起始和结束位置,如果某一段是回文,相应的格子就标记为真(true)。

  2. 寻找回文:你从珍珠串的一端开始,逐渐增加你检查的珍珠数量(这由变量c表示,它代表当前检查的子串长度减去1)。对于每一段可能的珍珠组合,你使用放大镜来检查:

    • 如果这段珍珠的两端字母相同,那么这可能是一个回文段。但是,要确认它确实是回文,还需要满足以下条件之一:

      • 这段珍珠非常短,长度为1或2,这意味着它们自动构成回文。

      • 如果这段珍珠更长,那么去掉两端的珍珠后,剩下的部分也必须是回文(即dp[i+1][j-1]true)。

  3. 更新最大回文长度:每次你发现一个新的回文段时,你会检查它的长度是否比你之前找到的任何回文段都要长。如果是,你就更新你记录的最大长度。

  4. 返回结果:经过整个珍珠串的检查后,你将找到的最长回文段的长度作为结果返回。

这个过程就像是用一个智能放大镜在一串珍珠上寻找隐藏的宝藏,你要找到最长的那段,无论从哪头看都一样美丽的宝藏(回文)。


**dp[i+1][j-1]以及为什么它不会导致i+1 > j-1的情况。**

在代码的循环结构中,我们是从较短的子串开始检查的,逐步扩展到较长的子串。这意味着,当我们在查看dp[i][j]时,其基于的较短子串(即dp[i+1][j-1])已经被检查过并赋值了。这是动态规划的一种常见策略,即解决小问题以帮助解决大问题。

现在,关于i+1 > j-1的疑问,让我们仔细看看for循环的控制变量c

  • c代表当前子串的长度减1。因此,当c = 2时,我们实际上是在处理长度为3的子串。

  • 对于长度为3(即c = 2)的子串,i+1j-1之间实际上没有空间,但因为我们是在检查首尾字符是否相同,所以这个条件在逻辑上是不需要考虑的。换句话说,对于长度为3的子串,dp[i+1][j-1]实际上是在检查一个单字符子串,它默认为真(因为我们在初始化dp数组时没有显式地处理这种情况,但这符合回文的定义)。

对于i+1 > j-1的担忧,这在循环的结构中是被自然避免的。我们从长度为1的子串开始检查,并且逐步增加长度。对于每个子串,我们都是基于已经计算好的更短子串的结果。当c较小时,我们不需要检查dp[i+1][j-1],因为子串太短,不能构成长度大于3的子串。只有当子串长度至少为3时(即c >= 2),i+1 <= j-1的情况才会出现,并且这时dp[i+1][j-1]的值已经在之前的步骤中被确定了。


如何保证max每次都被赋值时是最大的?

代码中的逻辑是遍历所有可能的子串,并且每次找到一个回文子串时,就更新max的值。关键点在于我们是按照子串长度从小到大进行遍历的。这意味着,当我们更新max时,我们已经考虑了所有更短的子串。因为c代表的是当前子串结束索引和开始索引的差值,所以c + 1实际上代表的是子串的长度。每次我们发现一个新的回文子串时,都会检查这个子串的长度,并且只有当它比所有之前发现的回文子串的长度都要长时,才会更新max的值。

NC28 最小覆盖子串

最小覆盖子串__牛客网 (nowcoder.com)

最小覆盖子串 (Minimum Window Substring) - 力扣 (LeetCode)

  1. 使用HashMap来统计字符串t中各字符的数量。

  2. 使用两个指针表示滑动窗口的左边界和右边界。

  3. 扩展右边界直到窗口包含了t中的所有字符。

  4. 然后逐步移动左边界以缩小窗口,同时更新最小覆盖子串的长度和起始位置。

  5. 注意处理字符计数和检查当前窗口是否覆盖了t中的所有字符。

    1. 如果全部数量满足

    2. 判断是否更新最小子串

      // 更新最小子串 if (ans[0] == -1 || r - l + 1 < ans[0]) {

    3. 移动left

    4. 移动right

import java.util.HashMap;
 import java.util.Map;
 ​
 class Solution {
     public String minWindow(String s, String t) {
         // 如果s的长度小于t,则直接返回空字符串,因为s中不可能包含t
         if (s.length() < t.length()) return "";
         
         // 用于统计t中各字符的数量
         Map<Character, Integer> map = new HashMap<>();
         for(char c: t.toCharArray()) {
             map.put(c, map.getOrDefault(c, 0) + 1);
         }
         
         // required表示需要找到的唯一字符的数量
         int required = map.size();
         // formed用于跟踪当前窗口中满足要求的唯一字符的数量
         int formed = 0;
         // 用于跟踪当前窗口中各字符的数量
         Map<Character, Integer> windowCounts = new HashMap<>();
         
         // ans数组用于存储最小覆盖子串的长度和起始位置
         int[] ans = {-1, 0, 0}; // {window length, left, right}
         
         // l和r分别代表滑动窗口的左右边界
         int l = 0, r = 0;
         
         // 开始遍历s
         while (r < s.length()) {
             char c = s.charAt(r);
             // 更新当前字符c在窗口中的数量
             windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);
             
             // 如果当前字符c是t中的字符,并且在窗口中的数量达到了t中的数量,则增加formed
             if (map.containsKey(c) && windowCounts.get(c).intValue() == map.get(c).intValue()) {
                 formed++;
             }
             
             // 当窗口包含了所有t中的字符时,尝试缩小窗口以找到最小覆盖子串
             while (l <= r && formed == required) {
                 c = s.charAt(l);
                 // 更新最小覆盖子串的信息
                 if (ans[0] == -1 || r - l + 1 < ans[0]) {
                     ans[0] = r - l + 1;
                     ans[1] = l;
                     ans[2] = r;
                 }
                 // 尝试移除左边界的字符,并更新窗口中的字符计数
                 windowCounts.put(c, windowCounts.get(c) - 1);
                 // 如果移除后导致某个必需的字符不再满足t中的要求,则减少formed
                 if (map.containsKey(c) && windowCounts.get(c) < map.get(c)) {
                     formed--;
                 }
                 // 缩小窗口
                 l++;
             }
             // 扩大窗口
             r++;
         }
         
         // 根据ans数组返回最小覆盖子串,如果ans[0]为-1,则返回空字符串
         return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1);
     }
 }

hw机试【深度搜索】

HJ41 称砝码
递归
  • weightSet.addAll(toAdd);

    • add(E e):这个方法用于向集合中添加单个元素e。如果此集合因调用而改变(即,添加了一个新元素),则返回true;如果这个元素已经存在于集合中,则不会添加,返回false

    • addAll(Collection<? extends E> c):这个方法用于将参数集合c中的所有元素添加到当前集合中。如果当前集合因调用而改变,则返回true;如果指定集合中的所有元素都已经存在于当前集合中(即,没有添加任何新元素),则返回false

  •  for(int i = 0; i < m.length; i++){
         // 对每种砝码重量都遍历一遍
     ​
         // 设置一个待加和的集合,也就是没统计到全部砝码,每统计一种砝码重量,就把可能的重量加和都放里面
         List<Integer> toAdd = new ArrayList<>();
     ​
         // 对于当前砝码重量种类,要加上此前的砝码重量的 重量 组合,而之前的就已经放在set里面了
         // 所以,要计算当前种类的砝码,要遍历之前每种可能的重量
         for(int existingWeight: set){
     ​
             // 添加遍历一种砝码重量的,所有数量构成的加和可能
             for(int j = 0; j <= x[i]; j++){
 
import java.util.*;
 ​
 public class Main {
     public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
         while(in.hasNext()){
             int n = in.nextInt(); // 砝码种数
             int[] weights = new int[n]; // 每种砝码的重量
             int[] numbers = new int[n]; // 每种砝码的数量
             for(int i = 0; i < n; i++){
                 weights[i] = in.nextInt();
             }
             for(int i = 0; i < n; i++){
                 numbers[i] = in.nextInt();
             }
             
             // 调用动态规划方法
             System.out.println(countDifferentWeights(weights, numbers));
         }
     }
     
     private static int countDifferentWeights(int[] weights, int[] numbers) {
         Set<Integer> weightSet = new HashSet<>();
         weightSet.add(0); // 初始化,重量0总是可达
         
         for (int i = 0; i < weights.length; i++) {
             List<Integer> toAdd = new ArrayList<>();
             // 遍历集合中已有的每个重量
             for (int existingWeight : weightSet) {
                 // 尝试添加0到numbers[i]个当前砝码,计算新的重量
                 for (int j = 1; j <= numbers[i]; j++) {
                     int newWeight = existingWeight + j * weights[i];
                     toAdd.add(newWeight);
                 }
             }
             // 将新计算出来的重量加入到集合中
             weightSet.addAll(toAdd);
         }
         
         return weightSet.size(); // 返回可达重量的数量
     }
 }
深度搜索(会超时)
 import java.util.*;
 ​
 public class Main {
     public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
         while(in.hasNext()){
             int n = in.nextInt(); // 砝码的种数
             int[] m = new int[n]; // 每种砝码的重量
             int[] x = new int[n]; // 每种砝码对应的数量
             for(int i = 0; i < n; i++){
                 m[i] = in.nextInt();
             }
             for(int i = 0; i < n; i++){
                 x[i] = in.nextInt();
             }
 ​
             Set<Integer> set = new HashSet<>();
             // 初始调用深度优先搜索,参数:当前考察的砝码索引0、当前总重量0、砝码重量数组、砝码数量数组、记录重量的集合
             dfs(0, 0, m, x, set);
 ​
             System.out.println(set.size()); // 可称出的不同重量数
         }
     }
 ​
     /**
      * 深度优先搜索函数
      * @param i 当前考察的砝码索引
      * @param sum 当前总重量
      * @param m 砝码重量数组
      * @param x 砝码数量数组
      * @param set 记录已经出现过的总重量
      */
     private static void dfs(int i, int sum, int[] m, int[] x, Set<Integer> set) {
         // 当所有砝码都考察完时,将当前总重量加入集合
         if (i == m.length) {
             set.add(sum);
             return;
         }
         // 对于每种砝码,可以选择0到x[i]个
         for (int j = 0; j <= x[i]; j++) {
             // 递归调用,考察下一种砝码,总重量增加j个当前砝码的重量
             dfs(i + 1, sum + j * m[i], m, x, set);
         }
     }
 }
 ​

二叉树

翻转二叉树

代码随想录 (programmercarl.com)

注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了

那么层序遍历可以不可以呢?依然可以的!只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!

递归
  1. 传入节点指针

  2. root == null

  3. left -> temp; right -> left; temp -> right

class Solution {
     public TreeNode invertTree(TreeNode root) {
         // 基本情况:如果当前节点为空,则直接返回null。
         // 这是递归的终止条件,防止对null节点进行操作。
         if(root == null) return null;
         
         // 递归调用invertTree函数,先尝试反转当前节点的左子树。
         invertTree(root.left);
         // 接着,递归反转当前节点的右子树。
         invertTree(root.right);
         
         // 在左右子树都被反转后,调用change方法交换当前节点的左右子节点。
         change(root);
         
         // 最后,返回当前节点。注意,对于根节点来说,这意味着返回更新后的树的根。
         return root;
     }
     
     private void change(TreeNode root){  
         // 临时保存当前节点的左子节点。
         TreeNode temp = root.left;
         // 将当前节点的左子节点更新为其右子节点。
         root.left = root.right;
         // 最后,将保存的原左子节点赋值给当前节点的右子节点,完成交换。
         root.right = temp;
     }
 }
 ​
BFS 广度优先搜索
  • 一定要写这一句 if(root == null) return null;

 class Solution{
     public TreeNode invertTree(TreeNode root){
         // 如果根节点为空,则直接返回null,表示没有需要反转的树。
         if(root == null) return null;
         
         // 使用一个双端队列(在这里作为队列使用)来进行层序遍历。
         Deque<TreeNode> deque = new LinkedList<>();
         // 将根节点加入队列,作为遍历的起点。
         deque.offer(root);
 ​
         // 只要队列不为空,就继续遍历。
         while(!deque.isEmpty()){
             // 当前层的节点数量。
             int size = deque.size();
             while(size-- > 0){
                 // 从队列中取出一个节点。
                 TreeNode temp = deque.poll();
                 // 交换这个节点的左右子节点。
                 change(temp);
                 // 如果当前节点的左子节点不为空,则将左子节点加入队列。
                 if(temp.left != null) deque.offer(temp.left);
                 // 如果当前节点的右子节点不为空,则将右子节点加入队列。
                 if(temp.right != null) deque.offer(temp.right);
             }
         }
         // 返回反转后的树的根节点。
         return root;
     }
     private void change(TreeNode root){  
         // 临时保存当前节点的左子节点。
         TreeNode temp = root.left;
         // 将当前节点的左子节点更新为其右子节点。
         root.left = root.right;
         // 将保存的原左子节点赋给当前节点的右子节点,完成交换。
         root.right = temp;
     }
 }
对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

递归三部曲

  1. 确定递归函数的参数和返回值

因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。

返回值自然是bool类型。

代码如下:

 bool compare(TreeNode* left, TreeNode* right)
  1. 确定终止条件

要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点

  • 左节点为空,右节点不为空,不对称,return false

  • 左不为空,右为空,不对称 return false

  • 左右都为空,对称,返回true

此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

  • 左右都不为空,比较节点数值,不相同就return false

此时左右节点不为空,且数值也不相同的情况我们也处理了。

代码如下:

 if (left == NULL && right != NULL) return false;
 else if (left != NULL && right == NULL) return false;
 else if (left == NULL && right == NULL) return true;
 else if (left->val != right->val) return false; // 注意这里我没有使用else

注意上面最后一种情况,我没有使用else,而是else if, 因为我们把以上情况都排除之后,剩下的就是 左右节点都不为空,且数值相同的情况。

  1. 确定单层递归的逻辑

此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

  • 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。

  • 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。

  • 如果左右都对称就返回true ,有一侧不对称就返回false 。

代码如下:

 bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
 bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
 bool isSame = outside && inside;                    // 左子树:中、 右子树:中(逻辑处理)
 return isSame;

如上代码中,我们可以看出使用的遍历方式,左子树左右中,右子树右左中,所以我把这个遍历顺序也称之为“后序遍历”(尽管不是严格的后序遍历)。

递归
 class Solution {
     public boolean isSymmetric(TreeNode root) {
         // 如果根节点为空,则树不对称(按照定义空树不是对称的,但实际上空树通常被认为是对称的,这里根据题目要求调整)
         if(root == null) return true;
         // 调用比较函数,比较根节点的左子树和右子树
         return compare(root.left, root.right);
     }
 ​
     private boolean compare(TreeNode left, TreeNode right){
         // 如果左节点为空而右节点不为空,或者左节点不为空而右节点为空,则不对称
         if(left == null && right != null) return false;
         if(left != null && right == null) return false;
         // 如果左右节点都为空,即在对称的位置上都没有子节点,则当前部分对称
         if(left == null && right == null) return true;
         // 如果左右节点的值不相同,则不对称
         if(left.val != right.val) return false;
 ​
         // 比较外侧:比较左子树的左子节点和右子树的右子节点
         boolean outcompare = compare(left.left, right.right);
         // 比较内侧:比较左子树的右子节点和右子树的左子节点
         boolean incompare = compare(left.right, right.left);
 ​
         // 只有当外侧和内侧都对称时,当前部分才对称
         return outcompare && incompare;
     }
 }
迭代

这里我们可以使用队列来比较两个树(根节点的左右子树)是否相互翻转,(注意这不是层序遍历

  1. 队列

  2. 添加左右

  3. 比较

  4. 再添加左左,右右,左右,右左

  • 注意 while(!deque.isEmpty()){

    if(left == null && right == null) continue; ,因为还要再向下迭代,所以要继续,直到所有都没有不对称

 class Solution{
     public boolean isSymmetric(TreeNode root){
         // 如果根节点为null,则树为空,按定义空树是对称的
         if(root == null) return true;
 ​
         // 使用一个双端队列(Deque)来支持从两端插入和移除元素,
         // 但在这里主要作为普通队列使用,用于层序遍历二叉树
         Deque<TreeNode> deque = new LinkedList<>();
 ​
         // 将根节点的左右子节点加入队列
         // 这是检查对称性的起始点
         deque.offer(root.left);
         deque.offer(root.right);
 ​
         // 只要队列不为空,就继续遍历
         while(!deque.isEmpty()){
             // 从队列中取出两个节点,分别代表要比较的对称节点
             TreeNode left = deque.poll();
             TreeNode right = deque.poll();
 ​
             // 如果两个节点都为null,说明这一部分是对称的,继续下一轮比较
             if(left == null && right == null) continue;
 ​
             // 如果一个节点为null而另一个不为null,说明树不对称,返回false
             if(left == null || right == null) return false;
 ​
             // 如果两个节点的值不相等,也说明树不对称,返回false
             if(left.val != right.val) return false;
 ​
             // 将下一层的对称节点加入队列,以待后续比较
             // 注意加入队列的顺序,它决定了比较的对称性
             deque.offer(left.left);
             deque.offer(right.right);
             deque.offer(left.right);
             deque.offer(right.left);
         }
 ​
         // 如果遍历完所有节点都符合对称性,说明整棵树是对称的,返回true
         return true;
     }
 }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++例子

#include<iostream> using namespace std;//抽象类 //抽象cpu类 class CPU { public:virtual void calcuate()0; }; //抽象显卡类 class VideoCard { public:virtual void display()0; }; //抽象内存条类 class Memory { public:virtual void storage()0;};//电脑类 clas…

leetcode 150.逆波兰表达式求值

题目 思路 逆波兰表达式也是经典的栈的应用问题。 先说什么是逆波兰表达式&#xff08;也叫后缀表达式&#xff09; 我们习惯的是这样的表达式&#xff1a;1 2 / 3 ,这也叫中缀表达式。 但是对于计算机来说不好理解&#xff0c;当从左扫描到 2 的时候还需要再判断2后面是什…

损失函数篇 | YOLOv8更换损失函数之CIoU / DIoU / EIoU / GIoU / SIoU / WIoU

前言:Hello大家好,我是小哥谈。损失函数是机器学习中用来衡量模型预测值与真实值之间差异的函数。在训练模型时,我们希望通过不断调整模型参数,使得损失函数的值最小化,从而使得模型的预测值更加接近真实值。不同的损失函数适用于不同的问题,例如均方误差损失函数适用于回…

vue2从基础到高级学习笔记

在实际的工作中,我常使用vue的用法去实现效果,但是你要是问我为什么这样写,它的原理是啥就答不上来了。对vue的认知一直停留在表面,写这篇文章主要是为了理清并弄透彻vue的原理。 学习目标 1 学会一些基本用法的原理 2 弄懂vue核心设计原理 3 掌握vue高级api的用法 一 vue…

基于springboot+vue的小型诊疗预约平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

蓝桥杯-单片机基础8——上下位机的串口通信设置(附小蜜蜂课程代码)

蓝桥杯单片机组备赛指南请查看这篇文章&#xff1a;戳此跳转蓝桥杯备赛指南文章 本文章针对蓝桥杯-单片机组比赛开发板所写&#xff0c;代码可直接在比赛开发板上使用。 型号&#xff1a;国信天长4T开发板&#xff08;绿板&#xff09;&#xff0c;芯片&#xff1a;IAP15F2K6…

知识管理平台企业要怎么用?看完你就会了

在信息爆炸的现代社会&#xff0c;知识管理的重要性不言而喻。一个强大的知识管理平台&#xff0c;可以让团队分享和查找知识变得更容易&#xff0c;提升知识管理效率和整体工作效率。本文将引导你了解如何有效地利用知识管理平台。 1.确定目标和需求 在使用知识管理平台之前…

每日一题 --- 设计链表[力扣][Go]

设计链表 题目&#xff1a;707. 设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则…

使用ollama + webui 运行任意大模型

安装ollama https://hub.docker.com/r/ollama/ollama docker run -d -v ~/Documents/work/softs/docker/ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama验证安装 # 进入容器docker exec -it ollama bash # 运行大模型 ollama run llama2 # 发送请求&…

硬件学习件Cadence day15 做个笔记--PCB需要生成的文件格式

1.PCB生产文件类型 如下&#xff1a; 1、*.ASM 文件&#xff1a;为电子装配图文件。焊接厂可能需要。 2、*.CAM 文件&#xff1a;为PCB制版厂所需文件。 3、*.DXF 文件&#xff1a;为导出的PCB结构CAD文件。 4、*.PCB 文件&#xff1a;为PCB设计文件。 5、*.SMD 文件&#xff1…

什么是浏览器指纹识别?Maskfog指纹浏览器有用吗?

浏览器指纹识别是好是坏&#xff1f;这现在确实是一个有争议的话题。83%的消费者经常或偶尔会根据浏览历史记录看到广告。其实这就是利用了浏览器指纹技术。 如果您想了解浏览器指纹识别是什么&#xff0c;那就看下去&#xff01; 一、什么是浏览器指纹识别 浏览器指纹是指无…

JavaSE——数据类型与变量

1. 数据类型 在 Java 中数据类型主要分为两类&#xff1a; 基本数据类型 和 引用数据类型 。 基本数据类型有 四类八种 &#xff1a; 1. 四类&#xff1a;整型、浮点型、字符型以及布尔型 2. 八种&#xff1a; 数据类型关键字内存占用范围字节型byte1 个字节-128~127短整型…

计算机实体安全

计算机实体安全定义&#xff1a; 对场地环境、设施、设备和载体、人员采取的安全对策和措施。 一、计算机可靠性与故障分析 1.1 计算机的可靠性 可靠性 (狭义) ■计算机在规定时间与条件下完成规定功能的 概率 ■规定条件&#xff1a;环境条件&#xff0c;使用条件&#xff0…

iOS应用审核问题解决方案及优化方法 ✨

摘要 本文将针对iOS应用提交审核时可能遇到的问题&#xff0c;如“你必须在Xcode中添加com.apple.developer.game-center密钥”&#xff0c;以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试&#xff0c;结合案例分析&#xff0c;提供了解决方案和优化方法&#x…

常用相似度计算方法总总结

一、欧几里得相似度 1、欧几里得相似度 公式如下所示&#xff1a; 2、自定义代码实现 import numpy as np def EuclideanDistance(x, y):import numpy as npx np.array(x)y np.array(y)return np.sqrt(np.sum(np.square(x-y)))# 示例数据 # 用户1 的A B C D E商品数据 [3.3…

自己的博客阵地(互联网核心之一 DNS)

DNS(Domain Name System)是一种用于将易记的域名映射到计算机网络中的 IP 地址的系统。它充当互联网上计算机和网络设备的地址簿&#xff0c;使人们可以使用便于记忆的域名来访问网站&#xff0c;而不必记住复杂的数字IP地址。&#xff08;完全合格域名&#xff09; 名字号联系…

卡尔曼滤波跟踪自由落体的高度程序,带MATLAB例程

背景 已知一物体做自由落体运动,对其高度进行20次测量,测量值如下表:(g=9.80m/s2). 设高度的测量误差分布为: N(0, 1),该物体的初始高度h0和速度v0分布也为高斯分布,且: 试求该物体高度和速度的随时间变化的最优估计(matlab Kalman filters)。N(0, 1),该物体的初始高…

vs2019新建Qt工程中双击 .ui 文件无法打开

vs2019 中创建的 Qt 工程&#xff0c;在使用的过程中&#xff0c;经常会有&#xff1a;双击 .ui 文件&#xff0c;闪退的情况&#xff0c;也即 .ui 文件无法打开&#xff01; 针对该问题的详细解决步骤如下&#xff1a; 1、右击该 .ui 文件&#xff0c;选择“打开方式” 2、…

GuLi商城-商品服务-API-三级分类-网关统一配置跨域

参考文档&#xff1a; https://tangzhi.blog.csdn.net/article/details/126754515 https://github.com/OYCodeSite/gulimall-learning/blob/master/docs/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E%E2%80%94%E5%88%86%E5%B8%83%E5%BC%8F%E5%9F%BA%E7%A1%80.md 谷粒商城-day04-完…

LabVIEW比例流量阀自动测试系统

LabVIEW比例流量阀自动测试系统 开发了一套基于LabVIEW编程和PLC控制的比例流量阀自动测试系统。通过引入改进的FCMAC算法至测试回路的压力控制系统&#xff0c;有效提升了压力控制效果&#xff0c;展现了系统的设计理念和实现方法。 项目背景&#xff1a; 比例流量阀在液压…
最新文章