leetcode动态规划(python与c++)

1 . 斐波那契数  

class Solution:def fib(self, n: int) -> int:# if n==0:#     return 0# elif n==1:#     return 1# else:#     return self.fib(n-1)+self.fib(n-2)a =0b =1for i in range(n):a,b = b,a+breturn a
class Solution {
public:int fib(int n) {int a = 0, b = 1;for(int i = 0; i < n; i++){int temp = a;a = a + b;b = temp;}return a;}
};

2. 第 N 个泰波那契数

class Solution:def tribonacci(self, n: int) -> int:if n == 0:return 0if n <= 2:return 1dp = [0]*(n+1)dp[1] = 1dp[2] = 1for i in range(3, n+1):dp[i] = dp[i-3] + dp[i-2] + dp[i-1]return dp[-1]
class Solution {
public:int tribonacci(int n) {if(n == 0){return 0;}if(n <= 2){return 1;}vector<int> dp(n + 1, 0);dp[1] = 1;dp[2] = 1;for(int i = 3; i < n+1; i++){dp[i] = dp[i-3] + dp[i-2] + dp[i-1];}return dp[n];}
};

3. 爬楼梯

class Solution:def climbStairs(self, n: int) -> int:if n < 3:return na = 1b = 2for i in range(3, n + 1):a, b = b, a + breturn b
class Solution {
public:int climbStairs(int n) {if(n < 3){return n;}int a = 1, b = 2;for(int i = 3; i < n + 1; i++){int temp = b;b = a + b;a = temp;}return b;}
};

 4. 使用最小花费爬楼梯

class Solution:def minCostClimbingStairs(self, cost: List[int]) -> int:dp = [0]*len(cost)dp[0],dp[1] =cost[0],cost[1]for i in range(2,len(cost)):dp[i] = min(dp[i-1],dp[i-2])+cost[i]return min(dp[-1],dp[-2])
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();vector<int> dp(n, 0);dp[0] = cost[0];dp[1] = cost[1];for(int i = 2; i < n; i++){dp[i] = min(dp[i-1], dp[i-2]) + cost[i];}return min(dp[n-2], dp[n-1]);}
};

 5. 打家劫舍

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)if n < 2:return max(nums)dp = [0] * ndp[0] = nums[0]dp[1] = max(nums[1],nums[0])for i in range(2, n):dp[i] = max(dp[i-2]+nums[i], dp[i-1])return dp[-1]
class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();if(n == 0){return 0;}if(n == 1){return nums[0];}if(n == 2){return max(nums[0],nums[1]);}vector<int> dp(n, 0);dp[0] = nums[0];dp[1] = max(nums[0], nums[1]);for(int i = 2; i < n; i++){dp[i] = max(dp[i-2]+nums[i], dp[i-1]);}return dp[n-1];}
};

6. 打家劫舍 II

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)if n < 2:return max(nums)dp1 = [0]*ndp2 = [0]*ndp1[0] = 0dp1[1] = nums[1]dp2[0] = nums[0]dp2[1] = max(nums[0], nums[1])for i in range(2, n):dp1[i] = max(dp1[i-2]+nums[i], dp1[i-1])for i in range(2, n-1):dp2[i] = max(dp2[i-2]+nums[i], dp2[i-1])return max(dp1[-1], dp2[-2])

7. 删除并获得点数

class Solution:def deleteAndEarn(self, nums: List[int]) -> int:maxVal = max(nums)total = [0] * (maxVal + 1)for val in nums:total[val] += val# print(total)n = len(total)dp = [0]*nif n <=2:return max(total)dp[0] = total[0]dp[1] = max(total[0], total[1])for i in range(2, n):dp[i] = max(dp[i-1], dp[i-2] + total[i])return dp[-1]

 8. 跳跃游戏

class Solution:def canJump(self, nums: List[int]) -> bool:#贪心算法most_dis = 0for i in range(len(nums)):if i <= most_dis:most_dis = max(most_dis, nums[i] + i)if most_dis >= len(nums) - 1:return Truereturn False
class Solution {
public:bool canJump(vector<int>& nums) {int most_length = 0;for(int i = 0; i < nums.size(); i++){if(i <= most_length){most_length = max(nums[i] + i, most_length);}if(most_length >= nums.size() - 1){return true;}}return false;int n = nums.size();vector<bool> opt(n, false);opt[0] = true;for(int i = 1; i < n; i++){opt[i] = opt[i - 1] && nums[i-1] >= 1;nums[i] = max(nums[i - 1] - 1, nums[i]);}return opt[n-1];}
};

9. 跳跃游戏 II

class Solution {
public:int jump(vector<int>& nums) {int res = 0;int start = 0;int end = 1;int maxPos = 0;while(end < nums.size()){for(int i = start; i < end; i++){//能跳到的最远距离maxPos = max(maxPos, nums[i] + i);}start = end;//下一次起跳点范围开始的格子end = maxPos + 1;//下一次起跳点范围结束的格子res++;}return res;}
};

10. 最大子序和

class Solution:def maxSubArray(self, nums: List[int]) -> int:for i in range(1,len(nums)):nums[i]+=max(nums[i-1],0)return max(nums)
class Solution {
public:int maxSubArray(vector<int>& nums) {int n = nums.size();int max_num = nums[0];for(int i = 1; i < n; i++){nums[i] += max(nums[i-1], 0);max_num = max(nums[i], max_num);}return max_num;}
};

11. 环形子数组的最大和

题解:

class Solution:def maxSubarraySumCircular(self, nums: List[int]) -> int:dpmax = nums.copy()dpmin = nums.copy()sum_ = sum(nums)for i in range(1, len(nums)):dpmax[i] = max(dpmax[i-1]+nums[i], dpmax[i])for i in range(1, len(nums)):dpmin[i] = min(dpmin[i-1]+nums[i], dpmin[i])# print(dpmax)# print(dpmin)max_value = max(dpmax)min_value = min(dpmin)if (sum_ - min_value) == 0:return max_valueelse:return max(max_value, sum_ - min_value)
class Solution {
public:int maxSubarraySumCircular(vector<int>& nums) {int sum_ = nums[0];vector<int>dpmax(nums);vector<int>dpmin(nums);for(int i=1;i<nums.size();i++){dpmax[i]=max(dpmax[i-1]+nums[i],nums[i]);dpmin[i]=min(dpmin[i-1]+nums[i],nums[i]);sum_ += nums[i];}int maxv=*max_element(dpmax.begin(),dpmax.end());int minv=*min_element(dpmin.begin(),dpmin.end());if(sum_ - minv == 0 ){return maxv;}else{return max(maxv, sum_ - minv);}}
};

12. 最佳观光组合

class Solution:def maxScoreSightseeingPair(self, values: List[int]) -> int:# n = len(values)# max_score = float('-inf')# for i in range(n):#     for j in range(i+1, n):#         max_score = max(max_score, values[i]+values[j]+i-j)# return max_scoren = len(values)mx = values[0]max_score = float('-inf')for i in range(1, n):max_score = max(max_score, mx + values[i] - i)mx = max(mx, values[i] + i)return max_score
class Solution {
public:int maxScoreSightseeingPair(vector<int>& values) {int n = values.size();int mx = values[0];int max_score = INT_MIN;for(int i = 1; i < n; i++){max_score = max(max_score, mx + values[i] - i);mx = max(mx, values[i] + i);}return max_score;}   
};

13. 买卖股票的最佳时机

class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0min_price = prices[0]max_profit = 0for i in range(1, len(prices)):min_price = min(prices[i], min_price)max_profit = max(max_profit, prices[i] - min_price)return max_profit
class Solution {
public:int maxProfit(vector<int>& prices) {if(prices.size() <= 1){return 0;}int max_profit = 0, min_price = prices[0];        for(int i = 1; i < prices.size(); i++){min_price = min(min_price, prices[i]);max_profit = max(max_profit, prices[i] - min_price);}return max_profit;   }
};

 14. 买卖股票的最佳时机 II

class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices)<=1:return 0res = 0for i in range(1, len(prices)):res += max(0, prices[i] - prices[i-1])return res
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();if(n <= 1){return 0;}int res = 0;for(int i = 1; i < n; i++){res += max(0, prices[i] - prices[i-1]);}return res;}
};

15.买卖股票的最佳时机含手续费

class Solution:def maxProfit(self, prices: List[int], fee: int) -> int:dp = [[0 for i in range(2)] for i in range(len(prices))]dp[0][1] = -prices[0]for i in range(1, len(prices)):dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee)dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])# print('==dp:', dp)return dp[-1][0]

16.最佳买卖股票时机含冷冻期

 

class Solution:def maxProfit(self, prices: List[int]) -> int: if len(prices)<=1:return 0       dp = [[0 for i in range(2)] for i in range(len(prices))]# print('==dp:', dp)dp[0][1] = -prices[0]dp[1][0] = max(dp[1 - 1][0], dp[1 - 1][1] + prices[1])dp[1][1] = max(dp[1-1][1], -prices[1])for i in range(2, len(prices)):dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])dp[i][1] = max(dp[i - 1][1], dp[i - 2][0] - prices[i])# print('==dp:', dp)return dp[-1][0]#返回没有的最大利润

16-1. 单词拆分

思路1:动态规划

#动态规划 dp[i]表示 s 的前 i 位是否可以用 wordDict 中的单词表示,
#
class Solution:def wordBreak(self, s, wordDict):n = len(s)dp = [False] * (n + 1)dp[0] = Truefor i in range(n):for j in range(i+1, n+1):if dp[i] and (s[i:j] in wordDict):dp[j] = Trueprint('==dp:', dp)return dp[-1]
s = "leetcode"
wordDict = ["leet", "code"]
sol = Solution()
res=  sol.wordBreak(s, wordDict)
print('==res:', res)

c++实现:

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {int n = s.size();unordered_set<string> wordDictSet;for (auto word: wordDict) {wordDictSet.insert(word);}        vector<bool> dp(n+1, false);dp[0] = true;for(int i = 0; i < n; i++){for(int j = i+1; j < n+1; j++){                if(dp[i] && wordDictSet.find(s.substr(i, j - i)) != wordDictSet.end())                 {// cout<<"s.substr(i, j - i):"<<s.substr(i, j - i)<<endl;dp[j] = true;}}}return dp[n];}
};

思路2:回溯加缓存


#递归 lru_cache用于缓存 将数据缓存下来 加快后续的数据获取 相同参数调用时直接返回上一次的结果
import functools
class Solution:@functools.lru_cache()def helper(self, s):if len(s) == 0:return Trueres = Falsefor i in range(1, len(s)+1):if s[:i] in self.wordDict:res = self.helper(s[i:]) or resreturn resdef wordBreak(self, s, wordDict):self.wordDict  = wordDictreturn self.helper(s)
s = "leetcode"
wordDict = ["leet", "code"]
# s = "aaaaaaa"
# wordDict = ["aaaa", "aaa"]
# s= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"
# wordDict = ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
sol = Solution()
res=  sol.wordBreak(s, wordDict)
print('==res:', res)

16-2.单词拆分 II

思路:递归 


class Solution:def helper(self, s, wordDict, memo):if s in memo:#递归终止条件return memo[s]if s=='':#递归终止条件return []res = []for word in wordDict:if not s.startswith(word):continueif len(word)==len(s):#匹配上刚好相等res.append(word)else:#匹配上 但是字符还没到最后rest = self.helper(s[len(word):], wordDict, memo)for tmp in rest:tmp = word+ " "+ tmpres.append(tmp)print('==res:', res)print('==memo:', memo)memo[s] = resreturn resdef wordBreak(self, s, wordDict):if s=='':return []return self.helper(s, wordDict, memo={})
s = "catsanddog"
wordDict = ["and", "cat", "cats", "sand", "dog"]
# s = "cat"
# wordDict = ["cat"]
sol = Solution()
res = sol.wordBreak(s, wordDict)
print(res)

 17-1,盛最多水的容器

求Max{(j-i) * Min( h(i), h(j) )}, 

height=[2,8,1,5,9,3,4]

暴力法: 超出时间限制

#解法1
class Solution:def maxarea(self,height):max_area=0for i in range(len(height)-1):for j in range(i+1,len(height)):if (j-i)*min(height[i],height[j])>max_area:max_area=(j-i)*min(height[i],height[j])index_i=iindex_j=jreturn index_i,index_j,max_areas=Solution()
height=[2,8,1,5,9,3,4]
i,j,max_area=s.maxarea(height)
print(i,j,max_area)

分析:暴力法时间复杂度为O(n2),想想看,

  1. 如果 h(7) >= h(1),我们还有必要再遍历h(6),h(5),...,h(2)吗,其实不用,这便是暴力算法的冗余之处,多做了很多次无用的遍历,i = 1这趟遍历中,最大面积一定为 (7-1) * h(1) ;

  2. 如果 h(7) < h(1),我们再尝试h(6),如果h(6)>=h(1),那么在i = 1这趟遍历中的面积最大为(6-1) * h(1),没必要再试h(5)了,依次这样下去。

动态规划:

  1. 面积最大值初始值设定 maxarea;

  2. i, j 分别指向索引两头,动态交替地调整 i, j ,进而尝试取得较大的相对高度,这个调整的策略是关键,同时,更新目标函数即面积的最大值,如果大于maxarea,则更新;

  3. 直到 i > j 为止;

  4. 返回最大值法

时间复杂度为 O(n),空间复杂度为 O(1) 。 

#解法2
class Solution:def maxarea(self,height):left=0right=len(height)-1max_area=0while left<right:max_area = max(max_area,(right - left) * min(height[left], height[right]))if height[left]<height[right]:left+=1else:right-=1# index_i = left# index_j=rightreturn max_areas=Solution()
height=[2,8,1,5,9,3,4]
max_area=s.maxarea(height)
print(max_area)

17-2:接雨水

思路1.暴力法  对于i处能存的水,向右向左分别找到最大的值,在取这两值中的最小值减去此刻的值就是能存的水,超时O(n^2)

class Solution:def trap(self, height):res = 0n = len(height)for i in range(1, n):print('==i:', i)left_max, right_max = 0, 0for j in range(i, -1, -1):#往左搜索left_max = max(left_max, height[j])for j in range(i, n):#往右搜索right_max = max(right_max, height[j])print('==left_max:', left_max)print('==right_max:', right_max)res +=min(right_max, left_max) - height[i]print('res:', res)return resheight = [0,1,0,2,1,0,1,3,2,1,2,1]
sol = Solution()
sol.trap(height)

思路2.优化,双指针

#某个位置i处,它能存的水,取决于它左右两边(left_max,right_max)的最大值中较小的一个。
#对于位置left而言,它左边最大值一定是left_max,右边最大值“大于等于”right_max,
# 这时候,如果left_max<right_max成立,那么它就知道自己能存多少水了。
# 无论右边将来会不会出现更大的right_max,都不影响这个结果。
# 所以当left_max<right_max时,我们就希望去处理left下标,反之,我们希望去处理right下标。O(n)
class Solution:def trap(self, height):left,right =0,len(height)-1left_max,right_max =0,0res = 0while left<=right:if left_max <right_max:res+=max(0, left_max - height[left])left_max = max(left_max, height[left])left+=1else:res += max(0, right_max - height[right])right_max = max(right_max, height[right])right -= 1print('==res:', res)return resheight = [0,1,0,2,1,0,1,3,2,1,2,1]
sol = Solution()
sol.trap(height)

c++实现:

class Solution {
public:int trap(vector<int>& height) {int left = 0, right = height.size() - 1;int left_max = 0, right_max = 0;int res = 0;while(left <= right){if(left_max < right_max){res += max(0, left_max - height[left]);left_max = max(height[left], left_max);left++;}else{res += max(0, right_max - height[right]);right_max = max(height[right], right_max);right--;}}return res;}
};

思路3:动态规划

开出两个数组,一个用于统计坐边最大值,一个用于统计右边最大值,这样最终该点的雨水就是当前点的短板减去当前值。

class Solution:def trap(self, height: List[int]) -> int:length = len(height)if length == 0:return 0left_max = [0 for i in range(length)]left_max[0] = height[0]right_max = [0 for i in range(length)]right_max[-1] = height[-1]for i in range(1, length):left_max[i] = max(left_max[i-1], height[i])for i in range(length-2, -1, -1):right_max[i] = max(right_max[i + 1], height[i])res = 0for i in range(length):res += min(left_max[i], right_max[i]) - height[i]return res

c++实现 :

class Solution {
public:int trap(vector<int>& height) {int res = 0;int length = height.size();if (length == 0){return res;}vector<int> left_max(length, 0);vector<int> right_max(length, 0);left_max[0] = height[0];right_max[length-1] = height[length-1];for (int i=1; i<length; i++){left_max[i] = max(left_max[i-1], height[i]);}for (int i=length-2; i>=0; i--){right_max[i] = max(right_max[i+1], height[i]);}for (int i=0; i<length; i++){res += min(right_max[i], left_max[i]) - height[i];}return res;}
};

18. 等差数列划分

class Solution:def numberOfArithmeticSlices(self, nums: List[int]) -> int:n = len(nums)if n <= 1:return 0dis = nums[1] - nums[0]res = 0temp = 0for i in range(2, n):if nums[i] - nums[i-1] == dis:temp += 1else:dis = nums[i] - nums[i-1]temp = 0res += tempreturn res

19. 解码方法

class Solution:def numDecodings(self, s: str) -> int:n = len(s)f = [1] + [0] * nfor i in range(1, n + 1):if s[i-1] != '0':f[i] += f[i-1]if i > 1 and s[i-2] != '0' and int(s[i-2:i])<=26:f[i] += f[i-2]return f[n]

20-1:丑数

思路:判断是否能整除2,3,5依次整除下去,将不能整除和1进行判断就知道是否是丑数了

class Solution:def isUgly(self, n: int) -> bool:if n <= 0: return Falsewhile((n % 2) == 0):n /= 2while((n % 3) == 0):n /= 3while((n % 5) == 0):n /= 5return n == 1

c++循环实现:

class Solution {
public:bool isUgly(int n) {if(n <= 0){return false;}while((n % 2) == 0){n /= 2;}while((n % 3) == 0){n /= 3;}while((n % 5) == 0){n /= 5;}return n == 1;}
};

c++递归实现:


//递归写法
class Solution {
public:bool isUgly(int n) {if(n <= 0){return false;}while((n % 2) == 0){return isUgly(n / 2);}while((n % 3) == 0){return isUgly(n / 3);}while((n % 5) == 0){return isUgly(n / 5);}return n == 1;}
};

20-2.丑数

思路:题目要求的这个数字一定是由单个或者多个2,3,5的乘积,如果从小到大去枚举在判断是否由2,3,5乘积组成,工作量会很大,所以考虑用2,3,5从下往上递推,需要开辟空间为n的数组,采用动态规划,2,3,5分别有三个索引,如果满足要求的数字等于2,3,5的倍数乘积,那么就直接将索引加1.

python代码:

class Solution:def nthUglyNumber(self, n):dp, index_two, index_three, index_five = [1] * n, 0, 0, 0for i in range(1, n):two = dp[index_two] * 2three = dp[index_three] * 3five = dp[index_five] * 5dp[i] = min(two, three, five)if two==dp[i]:index_two+=1if three==dp[i]:index_three+=1if five==dp[i]:index_five+=1print('==dp:', dp)return dp[-1]n = 11
sol = Solution()
sol.nthUglyNumber(n)

c++代码:

class Solution {
public:int nthUglyNumber(int n) {vector<int> dp(n,1);int index_two=0;int index_three=0;int index_five=0;for (int i=1;i<n;i++){int two = dp[index_two]*2;int three = dp[index_three]*3;int five = dp[index_five]*5;dp[i] = min(min(two, three), five);if (dp[i]==two){index_two++;}if (dp[i]==three){index_three++;}if (dp[i]==five){index_five++;}}return dp[n-1];}
};

21.不同的二叉搜索树

思路:卡塔兰数

将 1⋯(i−1) 序列作为左子树,将 (i+1)⋯n 序列作为右子树。接着我们可以按照同样的方式递归构建左子树和右子树。

在上述构建的过程中,由于根的值不同,因此我们能保证每棵二叉搜索树是唯一的.也就得到卡塔兰数

class Solution(object):def numTrees(self, n):""":type n: int:rtype: int"""#状态方程 和G(j-1) * G(n-j)dp = [0]*(n+1)#0 1树都为1dp[0], dp[1] = 1, 1for i in range(2,n+1):for j in range(1,i+1):dp[i] += dp[j-1]*dp[i-j]# print('==dp:', dp)return dp[-1]

c++实现:

class Solution {
public:int numTrees(int n) {vector<int> res(n+1,0);    res[0] = 1;res[1] = 1;for (int i=2;i<n+1;i++){for (int j=1;j<i+1;j++){res[i] += res[j-1] * res[i-j];}}return res[n];}   
};

22. 杨辉三角

python:

class Solution:def generate(self, numRows: int) -> List[List[int]]:res = []for i in range(numRows):temp = [0]*(i+1)for j in range(i + 1):if j == 0 or i == j:temp[j] = 1else:temp[j] = res[i-1][j] + res[i-1][j-1]res.append(temp)return res

c++:

class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>> res;for(int i = 0; i < numRows; i++){vector<int> temp(i+1, 0);for(int j = 0; j < i+1; j++){if(j == 0 || i == j){temp[j] = 1;}else{temp[j] = res[i-1][j-1] + res[i-1][j];}}res.push_back(temp);}return res;}
};

 23. 杨辉三角 II

python: 

class Solution:def getRow(self, rowIndex: int) -> List[int]:res = [0]*(rowIndex+1)res[0] = 1for i in range(rowIndex + 1):for j in range(i, 0, -1):res[j] += res[j-1]return res

 c++:

class Solution {
public:vector<int> getRow(int rowIndex) {vector<int> res(rowIndex+1, 0);res[0] = 1;for(int i = 1; i < rowIndex + 1; i++){for(int j = i; j > 0; j--){res[j] += res[j-1];}}return res;}
};

24.最小路径和

思路:动态规划 dp[i][j] = min(dp[i-1][j],dp[i][j-1])+v[i][j]


import numpy as np
#dp[i][j] = min(dp[i-1][j],dp[i][j-1])+v[i][j]
class Solution:def minPathSum(self, grid):h = len(grid)w = len(grid[0])dp = [[0 for i in range(w)] for j in range(h)]dp[0][0] = grid[0][0]for i in range(1, h):dp[i][0] = dp[i-1][0]+grid[i][0]for i in range(1, w):dp[0][i] = dp[0][i-1]+grid[0][i]print('==np.array(dp):\n', np.array(dp))for i in range(1, h):for j in range(1, w):dp[i][j] = min(dp[i-1][j],dp[i][j-1])+grid[i][j]print('==np.array(dp):\n', np.array(dp))return dp[-1][-1]
grid = [[1,3,1],[1,5,1],[4,2,1]]
sol = Solution()
sol.minPathSum(grid)

c++:

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {//dp[i][j] = min(dp[i-1][j], dp[i][j-1])+matrix[i][j]int m = grid.size();int n = grid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));dp[0][0] = grid[0][0];for(int i = 1; i < m; i++){dp[i][0] = dp[i-1][0] + grid[i][0];}for(int j = 1; j < n; j++){dp[0][j] = dp[0][j-1] + grid[0][j];}for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];}}return dp[m-1][n-1];}
};

25. 下降路径最小和

状态转移方程:(注意边界) 

dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1])+matrix[i][j]

python:

class Solution:def minFallingPathSum(self, matrix: List[List[int]]) -> int:#dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1])+matrix[i][j]n = len(matrix)# dp = [[0 for i in range(n)] for i in range(n)]# for i in range(n):#     dp[0][i] = matrix[0][i]for i in range(1, n):for j in range(n):if j == 0:matrix[i][j] = min(matrix[i-1][j], matrix[i-1][j+1])+matrix[i][j]             elif j == n-1:matrix[i][j] = min(matrix[i-1][j-1], matrix[i-1][j])+matrix[i][j]   else:matrix[i][j] = min(matrix[i-1][j-1], matrix[i-1][j], matrix[i-1][j+1])+matrix[i][j]# print(dp)return min(matrix[-1])

c++:

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {//dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1])+matrix[i][j]int n = matrix.size();vector<vector<int>> dp(n, vector<int>(n, 0));for(int i = 0; i < n; i++){dp[0][i] = matrix[0][i];}for(int i = 1; i < n; i++){for(int j = 0; j < n; j++){if(j == 0){dp[i][j] = min(dp[i-1][j], dp[i-1][j+1])+matrix[i][j];}else if(j == n-1){dp[i][j] = min(dp[i-1][j-1], dp[i-1][j])+matrix[i][j];}else{dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i-1][j+1]))+matrix[i][j];}}}int min_value = *min_element(dp[n-1].begin(), dp[n-1].end());return min_value;}
};

26.三角形最小路径和

状态转移方程,注意边界 

dp[i][j] = min(dp[i-1][j-1],dp[i-1][j])+ matrix[i][j]

python:

class Solution:def minimumTotal(self, triangle: List[List[int]]) -> int:#dp[i][j] = min(dp[i-1][j-1],dp[i-1][j])+ matrix[i][j]for i in range(1, len(triangle)):for j in range(len(triangle[i])):if j == 0:triangle[i][j] = triangle[i-1][j] + triangle[i][j]elif j == i:triangle[i][j] = triangle[i-1][j-1] + triangle[i][j]else:triangle[i][j] = min(triangle[i-1][j-1], triangle[i-1][j]) + triangle[i][j]return min(triangle[-1])

c++: 

class Solution {
public:int minimumTotal(vector<vector<int>>& triangle) {int h = triangle.size();for(int i = 1; i < triangle.size(); i++){for(int j = 0; j < triangle[i].size(); j++){if(j == 0){triangle[i][j] = triangle[i-1][j] + triangle[i][j];}else if(j == i){triangle[i][j] = triangle[i-1][j-1] + triangle[i][j];}else{triangle[i][j] = min(triangle[i-1][j-1], triangle[i-1][j]) + triangle[i][j];}}}int min_value = *min_element(triangle[h - 1].begin(), triangle[h - 1].end());return min_value;}
};

27. 不同路径

 python:

class Solution:def uniquePaths(self, m: int, n: int) -> int:dp = [[0 for i in range(n)] for j in range(m)]for i in range(m):dp[i][0]  = 1for i in range(n):dp[0][i]  = 1# print('==np.array(dp):', np.array(dp))for i in range(1,m):for j in range(1,n):dp[i][j] = dp[i-1][j]+dp[i][j-1]# print(np.array(dp))return dp[-1][-1]

c++:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));for(int i = 0; i < m; i++){dp[i][0] = 1;}for(int j = 1; j < n; j++){dp[0][j] = 1;}for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}return dp[m-1][n-1];}
};

28.不同路径 II

 

 python:

class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:if obstacleGrid[0][0] == 1:return 0m, n = len(obstacleGrid), len(obstacleGrid[0])dp = [[0 for _ in range(n)] for _ in range(m)]dp[0][0] = 1for i in range(1, m):if dp[i-1][0] == 1 and obstacleGrid[i][0] != 1:dp[i][0] = 1for j in range(1, n):if dp[0][j-1] ==1 and obstacleGrid[0][j] != 1:dp[0][j] = 1for i in range(1, m):for j in range(1, n):if obstacleGrid[i][j] != 1:dp[i][j] = dp[i-1][j] + dp[i][j-1]return dp[m-1][n-1]

c++:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size();int n = obstacleGrid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));if(obstacleGrid[0][0] == 1){return 0;}dp[0][0] = 1;for(int i = 1; i < m; i++){if(dp[i-1][0]==1 && obstacleGrid[i][0] != 1){dp[i][0] = 1;}                }for(int j = 1; j < n; j++){if(dp[0][j-1] == 1 && obstacleGrid[0][j] != 1){dp[0][j] = 1;}                }for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){if(obstacleGrid[i][j] != 1){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}}return dp[m-1][n-1];}
};

29.最大正方形

python:

状态转移方程

matrix[i][j] == '1'

dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1

class Solution:def maximalSquare(self, matrix: List[List[str]]) -> int:h = len(matrix)w = len(matrix[0])dp = [[0 for j in range(w)] for i in range(h)]dp[0][0] = int(matrix[0][0])maxside = int(matrix[0][0])for i in range(1, h):dp[i][0] = int(matrix[i][0])maxside = max(maxside, dp[i][0]) for j in range(1, w):dp[0][j] = int(matrix[0][j])maxside = max(maxside, dp[0][j])for i in range(1, h):for j in range(1, w):if matrix[i][j] == '1':dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1                  maxside = max(maxside, dp[i][j])return maxside**2

c++:

class Solution {
public:int maximalSquare(vector<vector<char>>& matrix) {int m = matrix.size();int n = matrix[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));int maxside = matrix[0][0] - '0';dp[0][0] = matrix[0][0] -  '0';for(int i = 1; i < m; i++){dp[i][0] = matrix[i][0] - '0';maxside = max(maxside, dp[i][0]);}for(int j = 1; j < n; j++){dp[0][j] = matrix[0][j] - '0';maxside = max(maxside, dp[0][j]);}// cout<<maxside<<endl;for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){if(matrix[i][j] == '1'){dp[i][j] = min(dp[i][j-1], min(dp[i-1][j-1], dp[i-1][j])) + 1;maxside = max(maxside, dp[i][j]);}}}return maxside*maxside;}};

30.最长回文子串

思路:中心扩散或者动态规划

class Solution:def helper(self,left,right,s):while left>=0 and right<len(s) and s[left]==s[right]:left-=1right+=1if len(s[left+1:right])>len(self.res):self.res = s[left+1:right]def longestPalindrome(self, s: str) -> str:self.res = ''for i in range(len(s)):self.helper(i,i,s)self.helper(i,i+1,s)return self.res

 c++:

class Solution {
public:string res;void help(string s, int left, int right){while(left>=0 && right<s.size() && s[left]==s[right]){left--;right++;}left++;right--;if((right - left + 1) > res.size()){res = s.substr(left, right - left + 1);            }}string longestPalindrome(string s) {if(s.size()<=1){return s;}for(int i=0; i<s.size(); i++){help(s, i, i);help(s, i, i+1);}return res;}
};

动态规划:

class Solution:def longestPalindrome(self, s: str) -> str:size = len(s)# 特殊处理if size == 1:return s# 创建动态规划dynamic programing表dp = [[False for _ in range(size)] for _ in range(size)]# 初始长度为1,这样万一不存在回文,就返回第一个值(初始条件设置的时候一定要考虑输出)max_len = 1start = 0for j in range(1,size):for i in range(j):# 边界条件:# 只要头尾相等(s[i]==s[j])就能返回Trueif j-i<=2:if s[i]==s[j]:dp[i][j] = Truecur_len = j-i+1# 状态转移方程 # 当前dp[i][j]状态:头尾相等(s[i]==s[j])# 过去dp[i][j]状态:去掉头尾之后还是一个回文(dp[i+1][j-1] is True)else:if s[i]==s[j] and dp[i+1][j-1]:dp[i][j] = Truecur_len = j-i+1# 出现回文更新输出if dp[i][j]:if cur_len > max_len:max_len = cur_lenstart = ireturn s[start:start+max_len]

31.最长回文子序列

思路:动态规划

class Solution:def longestPalindromeSubseq(self, s: str) -> int:n = len(s)dp = [[0] * n for _ in range(n)]for i in range(n - 1, -1, -1):dp[i][i] = 1for j in range(i + 1, n):if s[i] == s[j]:dp[i][j] = dp[i + 1][j - 1] + 2else:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])return dp[0][n - 1]

32.最长递增子序列

思路:动态规划

python:

class Solution:def lengthOfLIS(self, nums: List[int]) -> int:if len(nums)==0:return 0opt = [1]*len(nums)for i in range(1, len(nums)):for j in range(i):if nums[i]>nums[j]:opt[i] = max(opt[i], opt[j]+1)# print('==value:', value)# opt[i] = value+1# print('==dp:', opt)return max(opt)

c++:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();vector<int> dp(n, 1);int max_value = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(nums[j] < nums[i]){dp[i] = max(dp[i], dp[j] + 1);max_value = max(dp[i], max_value);}}}return max_value;}
};

33.判断子序列

思路:双指针

class Solution:def isSubsequence(self, s: str, t: str) -> bool:#双指针i, j = 0, 0while i < len(s) and j < len(t):if s[i] == t[j]:i += 1j += 1else:j += 1if i == len(s):return Trueelse:return False

class Solution {
public:bool isSubsequence(string s, string t) {int i=0,j=0;while(i < s.size() && j < t.size()){if(s[i] == t[j]){i++;j++;}else{j++;}}if(i == s.size()){return true;}else{return false;}}
};

34-1.最长公共子序列

python: 

class Solution:def minDistance(self, word1: str, word2: str) -> int:m = len(word1)n = len(word2)dp = [[0 for i in range(n+1)] for i in range(m+1)]for i in range(1, m+1):dp[i][0] = ifor j in range(1, n+1):dp[0][j] = jfor i in range(m):for j in range(n):if word1[i] == word2[j]:dp[i+1][j+1] = dp[i][j]else:dp[i+1][j+1] = min(dp[i][j], dp[i+1][j], dp[i][j+1]) + 1return dp[m][n]

c++: 

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int m = text1.size();int n = text2.size();vector<vector<int>> dp(m+1, vector<int>(n+1, 0));for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(text1[i] == text2[j]){dp[i+1][j+1] = dp[i][j] + 1;}else{dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]);}}}return dp[m][n];}
};

34-2.最长公共字串

# # 动态规划解决最大公共子串问题
def find_lcsubstr(s1, s2):m = [[0 for i in range(len(s2) + 1)] for j in range(len(s1) + 1)]  # 生成0矩阵,为方便后续计算,比字符串长度多了一列print(m)mmax = 0  # 最长匹配的长度p = 0  # 最长匹配对应在si中的最后一位for i in range(len(s1)):for j in range(len(s2)):if s1[i] == s2[j]:m[i + 1][j + 1] = m[i][j] + 1if m[i + 1][j + 1] > mmax:mmax = m[i + 1][j + 1]p = i + 1print(p)return s1[(p - mmax):p], mmax  # 返回最长子串及其长度

 35.编辑距离

 编辑距离,又称Levenshtein距离(莱文斯坦距离也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数,如果它们的距离越大,说明它们越是不同。许可的编辑操作包括将一个字符替换成另一个字符插入一个字符删除一个字符

mat[i+1,j]+1表示增加操作
d[i,j+1]+1 表示删除操作
d[i,j]+temp表示替换操作,其中temp取0或1


import numpy as np# 相等的情况dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]+1, dp[i][j-1]+1)
# 不相等的情况dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1)
class Solution:def minDistance(self, word1, word2):dp = [[0 for i in range(len(word1) + 1)] for i in range(len(word2) + 1)]for i in range(len(word1) + 1):dp[0][i] = iprint('==np.array(dp):', np.array(dp))for i in range(len(word2) + 1):dp[i][0] = iprint('==np.array(dp):', np.array(dp))for i in range(len(word2)):for j in range(len(word1)):if word2[i] == word1[j]:dp[i+1][j+1] = dp[i][j]else:dp[i+1][j+1] = min(dp[i][j]+1, dp[i][j+1]+1, dp[i+1][j]+1)print('==np.array(dp):', np.array(dp))return dp[-1][-1]word1 = "horse"
word2 = "ros"
sol = Solution()
sol.minDistance(word1, word2)

c++实现:

class Solution {
public:int minDistance(string word1, string word2) {int h  = word1.size();int w  = word2.size();vector<vector<int>> opt(h + 1, vector<int>(w + 1, 0));for(int i = 0; i < h; i++){opt[i + 1][0] = i + 1;}for(int j = 0; j < w; j++){opt[0][j + 1] = j + 1;}for(int i = 0; i < h; i++){for (int j = 0; j < w; j++){if(word1[i] == word2[j]){opt[i + 1][j + 1] = opt[i][j];}else{opt[i + 1][j + 1] = min(opt[i][j] + 1, min(opt[i + 1][j] + 1, opt[i][j + 1] + 1));}}}return opt[h][w];}
};

36.零钱兑换

 思路:找准状态状转移方程,f代表选择银币的函数,则f(11)=f(11-1)+1或f(11)=f(11-2)+1或f(11)=f(11-5)+1,则一般方程为:

f(money) = min(f(money), f(money-coin)+1)

class Solution:def coinChange(self, coins: List[int], amount: int) -> int:#状态转移方程f(money) = min(f(money),f(money-coin)+1)f = [float('inf')] * (amount + 1)f[0] = 0# print('==f:', f)for i in range(1, amount + 1):for coin in coins:if i - coin >= 0:f[i] = min(f[i], f[i - coin] + 1)# print('==f:', f)return f[-1] if f[-1]!=float('inf') else -1

c++实现:

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1, INT_MAX-1);dp[0] = 0;for(int i = 1; i < amount + 1; i++){for(int j = 0; j < coins.size(); j++){if(i - coins[j] >= 0){dp[i] = min(dp[i - coins[j]] + 1, dp[i]);}}}if(dp[amount] == INT_MAX-1){return -1;}else{return dp[amount];}}
};

3​​​​​​​​​​​​​7:零钱兑换 II

思路1:回溯 会超时


# 组合问题 回溯 超时
class Solution:def backtrace(self, amount, start, coins, track):if amount == 0:  # 终止条件# self.res.append(track)self.res+=1returnfor i in range(start, len(coins)):  # 选择条件if coins[i] > amount:continue# store = track.copy()# track.append(coins[i])self.backtrace(amount - coins[i], i, coins, track)# track = storedef change(self, amount, coins):self.res = 0#[]coins = sorted(coins)self.backtrace(amount, 0, coins, [])return self.res# amount = 5
# coins = [2]
amount = 5
coins = [1, 2, 5]
# amount = 500
# coins = [3,5,7,8,9,10,11]
sol = Solution()
res = sol.change(amount, coins)
print('==res:', res)

思路2:当成完全背包问题,用dp

#dp[i][j] 硬币为i 金额为j的组合数
import numpy as np
class Solution:def change(self, amount, coins):if len(coins) == 0:if amount == 0:return 1else:return 0dp = [[0 for i in range(amount+1)] for j in range(len(coins))]print('==np.array(dp):', np.array(dp))dp[0][0] = 1for j in range(coins[0], amount+1, coins[0]):dp[0][j] = 1print('==np.array(dp):', np.array(dp))for i in range(1, len(coins)):print('==coins[i]:', coins[i])for j in range(amount+1):dp[i][j] = dp[i - 1][j]#不选if j >= coins[i]:#选 注意与0 1背包有一点不同dp[i][j] += dp[i][j - coins[i]]print('==np.array(dp):', np.array(dp))return dp[-1][-1]amount = 5
coins = [1, 2, 5]
sol = Solution()
sol.change(amount, coins)

c++实现:

class Solution {
public:int change(int amount, vector<int>& coins) {int m = coins.size();vector<vector<int>> dp(m, vector<int>(amount + 1, 0));dp[0][0] = 1;for(int j = coins[0]; j < amount + 1; j += coins[0]){dp[0][j] = 1;}for(int i = 1; i < m; i++){for(int j = 0; j < amount + 1; j++){dp[i][j] = dp[i-1][j];if(j >= coins[i]){dp[i][j] += dp[i][j - coins[i]];}}}return dp[m-1][amount];}
};

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

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

相关文章

互联网50年类脑架构技术演化图

作者&#xff1a;刘锋 计算机博士 互联网进化论作者摘要&#xff1a;不断的有著名科学家或企业家提出互联网已死&#xff0c;将被新技术取代&#xff0c;最近绘制了一幅互联网50年的技术演化图&#xff0c;试图说明互联网从1969年四台计算机的网状结构发展成2019类脑结构的过程…

小孔成像中四个坐标系转换

一.小孔成像基础知识: 1.1透镜成像原理 如图所示&#xff1a; 其中 u 为物距&#xff0c; f 为焦距&#xff0c;v 为相距。三者满足关系式&#xff1a; 相机的镜头是一组透镜&#xff0c;当平行于主光轴的光线穿过透镜时&#xff0c;会聚到一点上&#xff0c;这个点叫做焦点&…

这10项机器人领域的核心技术,你了解多少

来源&#xff1a;机器人创新生态NO 1&#xff0e;人机对话智能交互技术这项技术能让人类做到真正与机器智能的对话交流&#xff0c;机器人不仅能理解用户的问题并给出精准答案&#xff0c;还能在信息不全的情况下主动引导完成会话。当前这一块做得比较成熟的谷歌与Facebook。NO…

leetcode哈希表(python与c++)

1.整数转罗马数字 python: class Solution:def intToRoman(self, num: int) -> str:dict_ {1000:M, 900:CM, 500:D, 400:CD, 100:C, 90:XC, 50:L, 40:XL, 10:X, 9:IX, 5:V, 4:IV, 1:I}res for key in dict_:count num // keyres count * dict_[key]num % keyreturn res…

Yann LeCun、吴恩达的新年AI预测:强调“少样本学习”,AI恐慌在减少

来源&#xff1a;大数据文摘新年伊始&#xff0c;海外媒体VentureBeat电话访谈了包括吴恩达、Yann Lecun在内的四位人工智能领域领军者&#xff0c;询问了他们对于过去一年人工智能领域发展的看法&#xff0c;以及他们认为新一年人工智能和机器学习可能产生的突破。不约而同&am…

1.C#WinForm基础制作简单计算器

利用c#语言编写简单计算器&#xff1a; 核心知识点&#xff1a; MessageBox.Show(Convert.ToString(comboBox1.SelectedIndex));//下拉序号MessageBox.Show(Convert.ToString(comboBox1.SelectedItem));//下拉内容MessageBox.Show(Convert.ToString(comboBox1.SelectedText));/…

seaborn的一些画图

一.数据查看 数据集地址,用红白酒为例&#xff0e; import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl import numpy as np import seaborn as snswhite_wine pd.read_csv(winequality-white.csv, se…

后摩尔定律时代的芯片新选择!

来源&#xff1a;gizmodo摘要&#xff1a;很长一段时间以来&#xff0c;摩尔定律和它的最终结局一直就像房间里的大象&#xff0c;不容忽视。英特尔联合创始人戈登摩尔在1965年的一篇论文中预测&#xff0c;芯片中的晶体管数量每年将翻一番。更多的晶体管意味着更快的速度&…

MSE和Cross-entropy梯度更新比较

一.平方损失(MSE) Loss函数: 梯度: 由于x,y是已知的&#xff0c;故可以忽略掉 梯度更新: sigmoid函数: 可以看出 导数在z取大部分值&#xff0c;都是很小的&#xff0c;这样会使梯度更新慢&#xff0e; y为1或0是&#xff0c;当a1,w的梯度为0,a0,w的梯度为0&#xff0c;故就…

麦卡锡问答:什么是人工智能?

来源&#xff1a;科学网一、基本问题问&#xff1a;什么是人工智能&#xff1f;答&#xff1a;人工智能是研制智能机器尤其是智能计算机程序的科学与工程。它与使用计算机理解人类智能类似&#xff0c;但人工智能并不将它自己局限于生物意义上的方法。问&#xff1a;是的&#…

操作系统--多进程管理CPU

一.cpu管理直观做法 最只管想法cpu循环取址执行&#xff0c;所以只需要设好pc初值即可 存在问题:io会占用时间长&#xff0c;导致cpu利用率低. 所以需要不停切换&#xff0c;执行多个程序&#xff0c;也就是并发&#xff0e; 但是在切换的时候&#xff0c;除了记录返回地址&a…

胶囊网络、边缘计算:2018年13个最新人工智能发展趋势

来源&#xff1a;亿欧智库摘要&#xff1a; 美国知名研究机构CB Insights的报告《2018年必看的人工智能热门趋势》&#xff0c;对AI行业发展现状进行了深入研究剖析&#xff0c;并给出了2018年AI领域最值得关注的13个前沿发展趋势。趋势一&#xff1a;新蓝领的工作——机器人保…

清空输入缓冲区fflush()

转自&#xff1a;http://blog.csdn.net/21aspnet/article/details/174326 scanf( )函数可以接收输入的换行符&#xff0c;\n,(asci为10)&#xff0c;利用函数fflush(stdin),可以清空输入内存缓冲区。 // function name fflush // 清空一个流 ,2014--03--29 #include <std…

操作系统--用户级线程与内核级线程

一.多进程是操作系统基本图像 进程都是在内核进行 二.用户级线程 2.1线程引入 可以切指令不切表&#xff0c;也就是资源不动&#xff0c;指令执行分开&#xff0c;更加轻量化&#xff0c;从而提高效率&#xff0c;保留并发优点&#xff0c;避免进程切换代价&#xff0c;也就…

“新视野”和“最远点”的约会

NASA 设想的2014 MU69 太空岩石 来源&#xff1a;中国科学报当新年香槟将陌生人聚在一起时&#xff0c;一种不同的聚会正在外太阳系进行。在距地球近65亿公里的地方&#xff0c;美国宇航局&#xff08;NASA&#xff09;“新视野”号探测器创下了寻访迄今最遥远世界的纪录。这场…

C语言里的写文件

转载自&#xff1a;http://blog.csdn.net/shuimuzhiyuan/article/details/6908335 部分转载自&#xff1a;http://blog.csdn.net/lijun5635/article/details/13095883 一 、fopen()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。如: "B:TEST.DAT"…

操作系统--内核级线程实现

五段论 &#xff1a; 进入内核靠的是中断&#xff0c;fork是创建系统进程调用&#xff0c;进程由资源&#xff0b;执行序列组成&#xff0c;而创建执行序列其实就是创建线程&#xff0e; TSS:任务结构段 参考&#xff1a; 操作系统_哈尔滨工业大学_中国大学MOOC(慕课)…

一文看尽2018全年计算机视觉大突破

来源&#xff1a;极市平台摘要&#xff1a;计算机视觉领域同样精彩纷呈&#xff0c;与四年前相比GAN生成的假脸逼真到让人不敢相信&#xff1b;新工具、新框架的出现&#xff0c;也让这个领域的明天特别让人期待……2018&#xff0c;仍是AI领域激动人心的一年。计算机视觉领域同…

leetcode BFS(python+c++)

1.最小基因变化 思路&#xff1a;bfs搜索回溯 python: class Solution:def minMutation(self, start: str, end: str, bank: List[str]) -> int:library [A,C, G,T]queue [start]num 0vis set()while queue:size len(queue)for i in range(size):cur queue.pop(0)i…

北欧小国的宏大AI实验: 让1%的人口接受人工智能培训

编译&#xff1a; 机器之能 微胖摘要&#xff1a;芬兰希望在人工智能的实际应用方面占据一席之地&#xff0c;成为世界领先国家。2017 年 10 月&#xff0c;芬兰成为欧盟第一个将国家人工智能战略付诸实施的国家。在 2018 年 6 月发布的第二份报告中&#xff0c;政府估计&#…