题目链接
这类题的难点在于如何去表示这两个数组比较的状态,对于两个数组的比较状态,我们一般是定义一个二维的dp数组,之后就简单多了。还有需要注意的是,dp[i][j]表示的是[0,i-1]长度的nums[i]和[0,j-1]长度的nums[j]的最长公共子序列的长度,这有利于之后进行初始化以及遍历顺序。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int l1=text1.size();
int l2=text2.size();
vector> dp(l1+1,vector(l2+1,0));
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(text1[i-1]==text2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[l1][l2];
}
};
错因:对dp数组的含义掌握不清晰,递推公式前的判断条件写成了if(text1[i]==text2[j])。
题目链接
就是在上一道题的基础上套了一个壳子,代码和思路一模一样。找相同的元素其实就是子序列问题,求最多的连线其实就是最长公共子序列问题。
class Solution {
public:
int maxUncrossedLines(vector& nums1, vector& nums2) {
int l1=nums1.size();
int l2=nums2.size();
vector> dp(l1+1,vector(l2+1,0));
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(nums1[i-1]==nums2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[l1][l2];
}
};
题目链接
还是主要是明确dp数组的含义即可,题目让我们求最大连续子序和,所以dp数组的含义就是这个,关键是下标i表示哪个元素,dp[i]表示以nums[i]为结尾的最大连续子序和。
class Solution {
public:
int maxSubArray(vector& nums) {
int len=nums.size();
vector dp(len,0);//dp[i]表示以nums[i]为结尾的最大连续子序和
dp[0]=nums[0];
int result=dp[0];
for(int i=1;iresult) result=dp[i];
}
return result;
}
};
题目链接
方法一:最直接的思路,先排序,再把前k个数放到res数组中。(具体的快排代码还需研究)
class Solution {
public:
vector getLeastNumbers(vector& arr, int k) {
vector res;
sort(arr.begin(),arr.end());
for(int i=0;i
方法二:使用大顶堆,也就是优先级队列。因为我们想获得最小的前k个元素,如果用小顶堆的话,每次弹出元素的时候会把堆顶元素弹出,最后剩下的其实是最大的k个元素,所以应该选大顶堆。
class Solution {
public:
vector getLeastNumbers(vector& arr, int k) {
vector res(k);
priority_queue que;
for(auto x:arr){
que.push(x);
if(que.size()>k) que.pop();
}
for(int i=k-1;i>=0;i--){
res[i]=que.top();
que.pop();
}
return res;
}
};
和本题比较像的是栈与队列的347.前 K 个高频元素,可以看卡哥的讲解:视频链接
题目链接
思路:用一个大顶堆记录较小的数字,用小顶堆记录较大的数字,同时保证大顶堆里的元素数量-小顶堆元素数量=1/0。具体可以代入1,2,3,4理解一下。
class MedianFinder {
public:
/** initialize your data structure here. */
priority_queue maxheap;
priority_queue,greater> minheap;
MedianFinder() {
}
void addNum(int num) {
//先全都插入大顶堆
maxheap.push(num);
//数目相差超过1了,就平衡一下
if((maxheap.size()-minheap.size())>1){//确保相差是1或者是0,可以代入1,2,3,4理解一下
minheap.push(maxheap.top());
maxheap.pop();
}
if(minheap.size()>0&&maxheap.top()>minheap.top()){
int maxval=maxheap.top();
int minval=minheap.top();
maxheap.pop();
minheap.pop();
maxheap.push(minval);
minheap.push(maxval);
}
}
double findMedian() {
if((maxheap.size()+minheap.size())%2==1) return maxheap.top();
else return (maxheap.top()+minheap.top())/2.0;
}
};
错因:最后除以2的话,就是两个整数相加除以2,就会向下取整,需要除以2.0,这时c++会自动转为浮点数。