算法学习day13(动态规划)

一、打家劫舍III

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

父节点和子节点不能同时偷(因为是直接相连的房子)

dp[0]/dp[1]:分别代表该节点上不偷和偷的最大值

思路:在树形结构中,采用后序遍历,左右中的顺序,从下往上求每一个节点的最大价值。

如果该节点不偷,那么下一节点可以偷,也可以不偷,dp[0]=下一节点偷或不偷的最大值;

如果该节点偷,那么下一节点就不可以偷,dp[1]=root.val+left[0]+right[0];

代码:

class Solution {public int rob(TreeNode root) {int[] res=robTree(root);return Math.max(res[0],res[1]);}//递归函数public int[] robTree(TreeNode root){int[] result=new int[2];//终止条件        if(root==null)return result;//单层递归逻辑int[] left=robTree(root.left);int[] right=robTree(root.right);//该节点不偷 孩子节点就可以偷result[0]=Math.max(left[0],left[1])+Math.max(right[0],right[1]);//该节点偷,孩子节点就不能偷result[1]=root.val+left[0]+right[0];return result;}
}

股票问题

二、买卖股票的最佳时机I(一次遍历/动态规划)

一次遍历(贪心):

如果price[i]<minprice,更新minprice;

如果price[i]>=minprice,看price[i]-minprice是否大于maxprofit,大于的话就更新

代码:

class Solution {public int maxProfit(int[] prices) {int minprice = Integer.MAX_VALUE;int maxprofit = 0;for (int i = 0; i < prices.length; i++) {if (prices[i] < minprice) {minprice = prices[i];} else if (prices[i] - minprice > maxprofit) {maxprofit = prices[i] - minprice;}}return maxprofit;}
}
动态规划:

注意:题目要求是买入和卖出只能一次,也就是只能在某一天买入或者某一天卖出

1.dp[i][0/1]:0代表该天不持有股票,1代表该天持有股票。dp[i][0/1]:代表该天可以获得最大利润

2.递推公式:

    2.1 dp[i][0]可能是延续上一天的状态,也可能是在这一天把股票卖了。

        dp[i][0](第i天不持有股票)=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

    2.2 dp[i][1]可能是延续上一天的状态,也可能是在这一天买入股票
        dp[i][1]=Math.max(dp[i-1][1],-prices[i]);

3.初始化:dp[0][0]:0 dp[0][1]:-prices;

4.遍历:从1开始到prices.length

代码:

class Solution {public int maxProfit(int[] prices) {if(prices==null||prices.length==0)return 0;// dp[x][0]:第x天不持有股票;dp[x][1]:第x天持有股票int[][] dp = new int[prices.length][2];dp[0][0] = 0;dp[0][1] = -prices[0];//注意dp[i][1]的递推公式 只能买入/卖出一次和每天买入/卖出的区别for (int i = 1; i < prices.length; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = Math.max(dp[i - 1][1], - prices[i]);}return Math.max(dp[prices.length - 1][0], dp[prices.length - 1][1]);}
}

三、买卖股票的最佳时机II(贪心/动态规划)

可以在某一天买入,同一天卖出。买入卖出允许多次。

贪心:如果prices[i]>prices[i-1] 直接加利润
class Solution {public int maxProfit(int[] prices) {int sumProfit=0;for(int i=1;i<prices.length;i++){if(prices[i]-prices[i-1]>0){sumProfit+=prices[i]-prices[i-1];}}return sumProfit;}
}
动态规划:

这个题和I的区别在于:上一道题只能一天买入,一天卖出。买入卖出的次数仅是1;而这一道题买入卖出的次数可以是多次。因此在状态方程上要发生变化

递推公式:

    dp[i][0]可能是延续上一天的状态,也可能是在这一天把股票卖了。

        dp[i][0](第i天不持有股票)=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

    dp[i][1]可能是延续上一天的状态,也可能是在这一天买入股票
        dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

代码:

class Solution {public int maxProfit(int[] prices) {if (prices == null || prices.length == 0)return 0;// 定义dp数组int[][] dp = new int[prices.length][2];// 初始化dp数组dp[0][0] = 0;// 不占有股票dp[0][1] = -prices[0];// 占有股票for (int i = 1; i < prices.length; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);}return Math.max(dp[prices.length - 1][0], dp[prices.length - 1][1]);}
}

四、买卖股票的最佳时机III(只可以买卖两次)

dp[prices.length][5]:dp数组的五个状态

不操作:dp[i][0]=dp[i-1][0];

第一次持有:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

第一次不持有:dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);

第二次持有:dp[i][3]=Math.max(dp[i-1][3],dp[i-1][2]-prices[i]);

第二次不持有:dp[i][4]=Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);

初始化:

  dp[0][0] = 0;

  dp[0][1] = -prices[0];

  dp[0][2] = 0;

  dp[0][3] = -prices[0];

  dp[0][4] = 0;

代码:

class Solution {public int maxProfit(int[] prices) {if (prices == null || prices.length == 0)return 0;// 只能买卖两次 dp五种状态 不操作 第一次持有 第一次不持有 第二次持有 第二次不持有int[][] dp = new int[prices.length][5];// dp数组初始化dp[0][0] = 0;dp[0][1] = -prices[0];dp[0][2] = 0;dp[0][3] = -prices[0];dp[0][4] = 0;// 遍历数组for (int i = 1; i < prices.length; i++) {dp[i][0] = dp[i - 1][0];dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2]-prices[i]);dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);}return dp[prices.length-1][4];}
}

五、买卖股票的最佳时机IV(k次交易)

从III找出规律来,两次交易,dp状态会有五次。k次交易,dp状态就会有2k+1次。

定义dp数组:dp[prices.length][2*k+1];

状态分别是:第一次不操作;第一次占有/第一次不占有;第二次占有/第二次不占有;.....;第k次占有/第k次不占有

dp数组初始化:

  dp[0][0] = 0;

dp[0][1] = -prices[0];         dp[0][2] = 0; 第一次占有/不占有

dp[0][3] = -prices[0];         dp[0][4] = 0;  第二次占有/不占有

dp[0][2k-1]=-prices[0];      dp[0][2k]=0;  第k次占有/不占有

dp数组遍历:

不操作:dp[i][0]=dp[i-1][0];

第一次持有:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

第一次不持有:dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);

第二次持有:dp[i][3]=Math.max(dp[i-1][3],dp[i-1][2]-prices[i]);

第二次不持有:dp[i][4]=Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);

找规律:

等于0,   =dp[i-1][0];

不等于0,并且是偶数:+prices[i];

不等于0,并且是奇数:   -prices[i];

代码:

class Solution {public int maxProfit(int k, int[] prices) {if(prices==null||prices.length==0)return 0;//k次交易 定义dp数组int[][] dp=new int[prices.length][1+2*k];//初始化dp[0][0]=0;//不操作for(int i=1;i<1+2*k;i++){if(i%2==0){dp[0][i]=0;}else{dp[0][i]=-prices[0];}}//进行遍历dp数组for(int i=1;i<prices.length;i++){for(int j=0;j<1+2*k;j++){if(j==0){dp[i][0]=dp[i-1][0];}else if(j%2!=0){dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1]-prices[i]);}else if(j%2==0){dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1]+prices[i]);}}}return dp[prices.length-1][1+2*k-1];}
}

六、买卖股票的最佳时机(包含冷冻期)

冷冻期:在卖出股票后,无法在第二天在进行买入/卖出(冷冻期为一天)

dp[i][4]:四种状态 表示某一天某种状态下的最大利润

占有股票:dp[i][0]=Math.max(dp[i-1][0],dp[i-1][3]-prices[i],dp[i-1][1]-prices[i])

延续上一天占有股票的状态;冷冻期后的买入股票;不占有股票后的买入股票

不占有股票:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][3]);

延续上一天不占股票的状态;上一天卖出股票

卖出股票:dp[i][2]=dp[i-1][0]+prices[i];

上一天为占有股票

冷冻期:dp[i][3]=dp[i-1][2];

上一天为卖出股票

代码:

class Solution {public int maxProfit(int[] prices) {//剪枝?if(prices==null||prices.length==0)return 0;/**创建dp数组 0:持有股票 1:不持有股票 2:卖出股票 3:冷冻期*/int[][] dp=new int[prices.length][4];//初始化dp数组dp[0][0]=-prices[0];dp[0][1]=0;dp[0][2]=0;dp[0][3]=0;//遍历数组for(int i=1;i<prices.length;i++){//延续上一天占有股票的状态;不占有股票后的买入股票;冷冻期后的买入股票dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][1]-prices[i],dp[i-1][3]-prices[i]));//延续上一天的不持有股票;冷冻期后的不持有股票dp[i][1]=Math.max(dp[i-1][1],dp[i-1][3]);//上一天持有股票dp[i][2]=dp[i-1][0]+prices[i];//上一天为卖出股票dp[i][3]=dp[i-1][2];}return Math.max(dp[prices.length-1][1],Math.max(dp[prices.length-1][2],dp[prices.length-1][3]));}
}

返回最大利润:要进行比较,因为最大利润可能出现在不持有股票/卖出股票/冷冻期三种情况中。

七、买卖股票的最佳时机含手续费

思路:其实跟II差不多,但是多了一个手续费,这里我们规定在每次卖出的时候需要付手续费。因为卖出肯定是买入之后的,就是买入卖出整个操作需要付手续费。

改变:在dp公式需要作出改变;

不占有股票:dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);

占有股票:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

初始化:dp[0][0]=0;dp[0][1]=-prices[0];

代码:

class Solution {public int maxProfit(int[] prices, int fee) {//含有手续费 就会限制你进行买卖int[][] dp=new int[prices.length][2];//dp[i][0]:不占有股票 dp[i][1]:占有股票 买的时候扣手续费dp[0][0]=0;dp[0][1]=0-prices[0];//初始化dp数组for(int i=1;i<prices.length;i++){dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);}return dp[prices.length-1][0]; }
}

买卖股票的最佳时机总结:

I:只能有一次买入/一次卖出

不持有股票:dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

持有股票:dp[i][1]=Math.max(dp[i-1][1],-prices[i]);

II:可以进行多次买入/卖出

不持有股票:dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);

持有股票:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

III:只能进行两次买入/卖出

状态分为五种:不操作;第一次占有/第一次不占有;第二次占有/第二次不占有

dp[i][0]=dp[i-1][0];

dp[i][1]=dp[i-1][0]-prices[i];

dp[i][2]=dp[i-1][1]+prices[i];

dp[i][3]=dp[i-1][2]-prices[i];

dp[i][4]=dp[i-1][3]+prices[i];

有规律的。

IV:只能进行k次买入/卖出

状态共有:2k+1次。

dp[i][j]=dp[i-1][j-1]±prices[i];  j为偶数+;j为奇数-;

V:包含冰冻期

状态共有四种:

占有股票:dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][1]-prices[i],dp[i][3]-prices[i]));

不占有股票:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][3]);

卖出股票:dp[i][2]=dp[i-1][0]+prices[i];

冰冻期:dp[i][3]=dp[i-1][2];

VI:含有手续费

在II的基础上,添加手续费。每次在交易完成的时候要付出手续费,在卖出股票时候。

不持有股票:dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);

持有股票:dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);

子序列问题:

八、最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 

思路:

1.dp[i]:表示从0到i,最长子序列的长度

2.dp[i]=Math.max(dp[i],dp[j]+1);

递推公式如何来的:根据dp[i]的含义,要找到nums[j]<nums[i]的元素,然后在dp[j]的基础上+1;

但是nums[j]不仅仅有一个,因此每次取dp[i],和dp[j]+1的较大的。

3.初始化:所有元素初始化为1

4.遍历顺序从1开始。双层for循环寻找nums[j]<nums[i]的元素,并且更新dp[i]

注意:最大值不是dp[nums.length-1],而是dp数组中的最大值。

代码:

class Solution {public int lengthOfLIS(int[] nums) {//定义dp数组int[] dp=new int[nums.length];//初始化Arrays.fill(dp,1);//双层for循环遍历int max=1;for(int i=1;i<nums.length;i++){for(int j=0;j<i;j++){if(nums[j]<nums[i]){dp[i]=Math.max(dp[i],dp[j]+1);max=Math.max(max,dp[i]);}}}return max;}
}

九、最长连续递增序列(比较简单)

不需要双层for循环寻找比nums[i]小的元素了。因为题目要求子序列必须是连续的。

代码:

class Solution {public int findLengthOfLCIS(int[] nums) {int[] dp=new int[nums.length];Arrays.fill(dp,1);int max=1;for(int i=1;i<nums.length;i++){if(nums[i]>nums[i-1]){dp[i]=dp[i-1]+1;max=Math.max(max,dp[i]);}}return max;}
}

十、最长重复子数组

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 

思路:

1.dp[i][j]:遍历到i-1,j-1的最长公共子数组的长度

2.if(nums[i-1]==nums[j-0])dp[i][j]=dp[i-1][j-1]+1;

3.初始化都为0,因为是从i-1,j-1(-1 -1开始的)。相当于多加了一行一列,这样就不用多用两个循环去初始化原本的第一行第一列。让所有工作交给遍历

4.从i和j分别从1,1开始到nums1.length,nums2.length;

代码:

class Solution {public int findLength(int[] nums1, int[] nums2) {int len1=nums1.length;int len2=nums2.length;int max=0;int[][] dp=new int[len1+1][len2+1];for(int i=1;i<=len1;i++){for(int j=1;j<=len2;j++){if(nums1[i-1]==nums2[j-1]){dp[i][j]=dp[i-1][j-1]+1;max=Math.max(max,dp[i][j]);}}}return max;}
}

十一、最长公共子序列(和上一题类似也有不同)

不同:上一道题要求的是子数组是连续的,因此如果nums1[i]==nums2[j]的时候,dp[i][j]=dp[i-1][j-1]+1;况且只能由[i-1][j-1]而来;

而这一道题不要求序列是连续的,因此当text1.charAt(i-1)==text2.charAt(j-1) 的时候,dp[i][j]=dp[i-1][j-1]+1;如果不相等的话,可以由dp[i-1][j]和dp[i][j-1]得到。

类似:和上一题一样,为了减少初始化时for循环的复杂,多加一行一列,dp[len1+1][len2+1]。

然后初始化由遍历帮助我们完成

代码:

class Solution {public int longestCommonSubsequence(String text1, String text2) {int len1=text1.length();int len2=text2.length();int[][] dp=new int[len1+1][len2+1];int result=0;for(int i=1;i<=len1;i++){for(int j=1;j<=len2;j++){if(text1.charAt(i-1)==text2.charAt(j-1)){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);}result=Math.max(result,dp[i][j]);}}printfDp(dp);return result;}public void printfDp(int[][] dp){for(int[] arr:dp){for(int i:arr){System.out.print(i+" ");}System.out.println("");}}
}

十二、最大子序和(贪心/动态规划)

贪心:

如果前面的值是负的,那么就不加(加上拖后腿)

如果前面的值是正的,再加(加上更大)

代码:

    public int maxSubArray(int[] nums) {int result=Integer.MIN_VALUE;int count=0;for(int i=0;i<nums.length;i++){count+=nums[i];if(count>result)result=count;if(count<0)count=0;}return result;}
动态规划:

1.dp[i]:从0->i,最大的子序列的和

2.if(dp[i-1]>0)dp[i]=dp[i-1]+nums[i];else dp[i]=nums[i]

3.初始化:dp[0]=nums[0];

4.从i=1开始遍历

十三、判断子序列(双指针/动态规划)

双指针:

定义slow,fast指针。slow指向s串,fast指向t串。如果fast遍历到末尾以及之前,slow也可以遍历到末尾,那么就包含。

代码:

class Solution {public boolean isSubsequence(String s, String t) {int sLen=s.length();int tLen=t.length();if(sLen>tLen)return false;int slow = 0;int fast = 0;while(fast<tLen){if(slow==sLen)return true;else{if(t.charAt(fast)==s.charAt(slow)){slow++;}fast++;}}return slow==sLen;}
}

注意:如果是slow和fast同时到达末尾的话,那么while(fast<tLen)最后一次就没进去,但此时slow==sLen,就无法判断到。因此返回的时候应该写:return slow==sLen;

动态规划(类似于求最长公共子序列的长度):

如果最长子序列的长度==s串的长度,那么就返回true。

class Solution {public boolean isSubsequence(String s, String t) {int sLen = s.length();int tLen = t.length();if (sLen > tLen)return false;// 定义dp数组int[][] dp = new int[sLen + 1][tLen + 1];// 遍历dp数组(初始化dp数组放到遍历中)int max = 0;for (int i = 1; i <= sLen; i++) {for (int j = 1; j <= tLen; j++) {if (s.charAt(i - 1) == t.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);}max = Math.max(dp[i][j], max);}}printfDp(dp);System.out.println(max);return max == sLen;}public void printfDp(int[][] dp){for(int[] arr:dp){for(int i:arr){System.out.print(i+" ");}System.out.println(" ");}}

十四、不同的子序列(回溯法/动态规划)

回溯法:超时..

代码:

class Solution {StringBuilder sb = new StringBuilder();int count = 0;public int numDistinct(String s, String t) {if(s.length()<t.length())return 0;backTracking(s, t, 0);return count;}public void backTracking(String s, String t, int startIndex) {// 终止条件if (sb.toString().equals(t)) {count++;return;}if (startIndex >= s.length())return;// 单层递归逻辑for (int i = startIndex; i < s.length(); i++) {sb.append(s.charAt(i));backTracking(s, t, i + 1);sb.deleteCharAt(sb.length() - 1);}}
}
动态规划:

1.dp[i][j]:以i-1为结尾的s中有多少个以j-1为结尾的t (方便操作 不用初始化了)

2.递推公式(难以理解)

   if(s.charAt(i)==t.charAt(j))dp[i][j]==dp[i-1][j-1]+dp[i-1]dp[j];

   else dp[i][j]=dp[i-1][j];

 如何理解:

s[i-1]t[j-1] 不相等时
  • dp[i][j] = dp[i-1][j]
  • 解释:此时我们不能用 s[i-1] 来匹配 t[j-1],所以只能看 s[0...i-2] 中有多少个 t[0...j-1] 的子序列。
s[i-1]t[j-1] 相等时
  • dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
  • 解释:我们有两种选择:
    1. s[i-1] 来匹配 t[j-1]:此时我们需要看 s[0...i-2] 中有多少个 t[0...j-2] 的子序列,这就是 dp[i-1][j-1]
    2. 不用 s[i-1] 来匹配 t[j-1]:此时我们需要看 s[0...i-2] 中有多少个 t[0...j-1] 的子序列,这就是 dp[i-1][j]

3.初始化:dp[i][0]=1;dp[0][j]=0;

4.遍历顺序 1 1

代码:

class Solution {public int numDistinct(String s, String t) {int[][] dp = new int[s.length() + 1][t.length() + 1];for (int i = 0; i < s.length() + 1; i++) {dp[i][0] = 1;}for (int i = 1; i < s.length() + 1; i++) {for (int j = 1; j < t.length() + 1; j++) {if (s.charAt(i - 1) == t.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];}else{dp[i][j] = dp[i - 1][j];}}}return dp[s.length()][t.length()];}
}

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

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

相关文章

ubuntu 24 PXE Server (bios+uefi) 批量部署系统

pxe server 前言 PXE&#xff08;Preboot eXecution Environment&#xff0c;预启动执行环境&#xff09;是一种网络启动协议&#xff0c;允许计算机通过网络启动而不是使用本地硬盘。PXE服务器是实现这一功能的服务器&#xff0c;它提供了启动镜像和引导加载程序&#xff0c;…

dev c++ 添加osg包含目录失败

在dev c 中添加osg的包含目录&#xff1b; 编译程序&#xff0c;出现下图错误&#xff1b; 打开出错文件&#xff0c;修改编码为UTF-8&#xff0c; 错误还是没有消除&#xff1b; 根据资料&#xff0c;osg是基于opengl开发的&#xff1b;不过我也没在osg的目录下看到opengl的头…

2024-07-19 Unity插件 Odin Inspector10 —— Misc Attributes

文章目录 1 说明2 其他特性2.1 CustomContextMenu2.2 DisableContextMenu2.3 DrawWithUnity2.4 HideDuplicateReferenceBox2.5 Indent2.6 InfoBox2.7 InlineProperty2.8 LabelText2.9 LabelWidth2.10 OnCollectionChanged2.11 OnInspectorDispose2.12 OnInspectorGUI2.13 OnIns…

Training for Stable Diffusion

1.Training for Stable Diffusion 笔记来源&#xff1a; 1.Denoising Diffusion Probabilistic Models 2.最大似然估计(Maximum likelihood estimation) 3.Understanding Maximum Likelihood Estimation 4.How to Solve ‘CUDA out of memory’ in PyTorch 1.1 Introduction …

如何设计分布式锁?

1. 为什么需要使用分布式锁&#xff1f; 在实际项目中&#xff0c;经常会遇到多个客户端对同一个资源或数据进行访问&#xff0c;为了避免并发访问带来错误&#xff0c;就会对该资源或数据加一把锁&#xff0c;只允许获得锁的客户端进行操作。 总结来说&#xff0c;分布式锁是…

新能源汽车空调系统的四个工作过程

汽车空调制冷系统组成 1.汽车空调制冷系统组成 以R134a为制冷剂的汽车空调制冷系统主要包括压缩机、电磁离合器、冷凝器、 散热风扇、储液于燥器、膨胀阀、蒸发器、鼓风机、制冷连接管路、高低压检测 连接接头、调节与控制装置等组成。 汽车空调的四个过程 1压缩过程 传统车…

金融数据的pandas模块应用

金融数据的pandas模块应用 数据链接&#xff1a;https://pan.baidu.com/s/1VMh8-4IeCUYXB9p3rL45qw 提取码&#xff1a;c6ys 1. 导入所需基础库 import pandas as pd import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams[font.sans-serif][FangSong] mpl.rcP…

JAVA.1.新建项目

1.代码结构 2.如何创建项目 1.创建工程 至此&#xff0c;我们创建了我们的第一个工程 2.创建模块 可见已经有了p28的一个模块&#xff0c;删掉了再添加 展开src 3.创建包 4.新建类 5.编写代码 package demo1;public class Hello {public static void main(String[] args) {Sys…

华为od机试真题:火星符号运算(Python)

题目描述 已知火星人使用的运算符号为 #和$ 其与地球人的等价公式如下 x#y2*x3*y4 x$y3*xy2x y是无符号整数。地球人公式按照c语言规则进行计算。火星人公式中&#xff0c;# 号的优先级高于 $ ,相同的运算符&#xff0c;按从左往右的顺序计算 现有一段火星人的字符串报文&a…

基于Centos7搭建rsyslog服务器

一、配置rsyslog可接收日志 1、准备新的Centos7环境 2、部署lnmp环境 # 安装扩展源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo# 安装扩展源 yum install nginx -y# 安装nginx yum install -y php php-devel php-fpm php-mysql php-co…

UNiapp 微信小程序渐变不生效

开始用的一直是这个&#xff0c;调试一直没问题&#xff0c;但是重新启动就没生效&#xff0c;经查询这个不适合小程序使用&#xff1a;不适合没生效 background-image:linear-gradient(to right, #33f38d8a,#6dd5ed00); 正确使用下面这个&#xff1a; 生效&#xff0c;适合…

【TensorRT】Yolov5-DeepSORT 目标跟踪

Yolov5-DeepSORT-TensorRT 本项目是 Yolo-DeepSORT 的 C 实现&#xff0c;使用 TensorRT 进行推理 &#x1f680;&#x1f680;&#x1f680; 开源地址&#xff1a;Yolov5_DeepSORT_TensorRT&#xff0c;求 star⭐ ~ 引言 ⚡ 推理速度可达25-30FPS&#xff0c;可以落地部署&…

LeetCode-day20-2850. 将石头分散到网格图的最少移动次数

LeetCode-day20-2850. 将石头分散到网格图的最少移动次数 题目描述示例示例1&#xff1a;示例2&#xff1a; 思路代码 题目描述 给你一个大小为 3 * 3 &#xff0c;下标从 0 开始的二维整数矩阵 grid &#xff0c;分别表示每一个格子里石头的数目。网格图中总共恰好有 9 个石头…

5.java操作RabbitMQ-简单队列

1.引入依赖 <!--rabbitmq依赖客户端--> <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId> </dependency> 操作文件的依赖 <!--操作文件流的一个依赖--> <dependency><groupId>c…

如何在 Mac 上下载安装植物大战僵尸杂交版? 最新版本 2.2 详细安装运行教程问题详解

植物大战僵尸杂交版已经更新至2.2了&#xff0c;但作者只支持 Windows、手机等版本并没有支持 MAC 版本&#xff0c;最近搞到了一个最新的杂交 2.2 版本的可以在 Macbook 上安装运行的移植安装包&#xff0c;试了一下非常完美能够正常在 MAC 上安装运行&#xff0c;看图&#x…

Pytest测试框架的基本使用

目录 安装教程 Pytest命名约束 创建测试用例 执行测试用例 生成测试报告 参数化测试 pytest框架 pytest是目前非常成熟且功能齐全的一个测试框架&#xff0c;能够进行简单的单元测试和复杂的功能测试。还可以结合selenium/appnium进行自动化测试&#xff0c;或结合reques…

加拿大上市药品查询-加拿大药品数据库

在加拿大&#xff0c;药品的安全性、有效性和质量是受到严格监管的。根据《食品药品法案》的规定&#xff0c;所有药品制造商必须提供充分的科学证据&#xff0c;证明其产品的安全性和有效性。为此&#xff0c;加拿大卫生部建立了一个全面的药品数据库 &#xff08;DPD) &#…

【C++】类和对象——默认成员函数(下)

目录 前言拷贝构造1.概念2.特征3.总结 赋值重载运算符重载赋值运算符重载探讨传引用返回和传值返回的区别 const成员取地址及const取地址操作符重载 前言 上一讲我们已经说了关于C的默认成员函数中的两个——构造和析构函数。所谓默认成员函数也就是&#xff1a;用户没有显示定…

你的Type-c接口有几颗牙齿

C 口为啥不能混用 想想 C 口当年推出时给我们画的饼&#xff0c;“正反都能插&#xff0c;而且充电、传数据、连显示器等等&#xff0c;什么活都能干”&#xff0c;而实现这一切的前提全靠 C 口里面的 24 根针脚 这 24 根真叫呈中心对称分布&#xff0c;这种设计使得插头可以以…

iPhone手机上备忘录怎么设置字数显示

在日常生活和工作中&#xff0c;我经常会使用iPhone的备忘录功能来记录一些重要的想法、待办事项或临时笔记。备忘录的便捷性让我可以随时捕捉灵感&#xff0c;但有时候&#xff0c;我也会苦恼于不知道自己记录了多少内容&#xff0c;尤其是在需要控制字数的时候。 想象一下&a…