1.4学习博客

1.4学习博客
今天学习了贪心算法的基本思想,在两个基础题目中得到了运用,集合了题目本身的特点以及双指针的运用。
第一题:https://leetcode-cn.com/problems/partition-labels/
由于同一个字母只能出现在同一个片段,显然同一个字母的第一次出现的下标位置和最后一次出现的下标位置必须出现在同一个片段。因此需要遍历字符串,得到每个字母最后一次出现的下标位置。
在得到每个字母最后一次出现的下标位置之后,可以使用贪心算法和双指针的方法将字符串划分为尽可能多的片段
int max(int a,int b){
if(a<b)return b;
else{return a;}
}
int* partitionLabels(char * S, int* returnSize){
int start=0,end=0;
int i,abc[26];
for(i=0;i<26;i++)abc[i]=0;
for(i=0;i<strlen(S);i++)abc[S[i]-‘a’]=i;
returnSize=0;
int
p=(int*)malloc(sizeof(int)*strlen(S));
for(i=0;i<strlen(S);i++){
end=max(end,abc[S[i]-‘a’]);
if(i==end){
p[(*returnSize)++]=end-start+1;
start=end+1;
}
}
return p;
}
第二题:https://leetcode-cn.com/problems/score-after-flipping-matrix/
根据题意,可以先考虑所有的行翻转,再考虑所有的列翻转。为了得到最高的分数,矩阵的每一行的最左边的数都必须为 1。原来为1的保持,原来为0的则翻转。当将每一行的最左边的数都变为 1 之后,就只能进行列翻转了。为了使得总得分最大,我们要让每个列中 1 的数目尽可能多。因此,我们扫描除了最左边的列以外的每一列,如果该列 0 的数目多于 1 的数目,就翻转该列,其他的列则保持不变
部分代码:

int max(int a,int b){
if(a>b)return a;
else{return b;}
}
int matrixScore(int** A, int ASize, int* AColSize){
int result=0;
int m,n,k;
m=ASize;
n=AColSize[0];
result=m*(1<<(n-1));//m列的最大位1能提供m个2的n-1次
for(int j=1;j<n;j++){//从左往右数第一列编号为0,第二列编号为1
k=0;
for(int i=0;i<m;i++){
if(A[i][0]==1)k+=A[i][j];
else{k+=1-A[i][j];}
}
k=max(k,m-k);//取0和1中最大的
result+=k*(1<<(n-j-1));//第j列提供的数值与之前的值相加
}
return result;
}
小结:贪心算法的使用需要对题目题意了解透彻,才能在正确的地方使用贪心算法,即结合题目本身特点;可以结合其他技巧来提高效率,例如双指针等。

猜你喜欢

转载自blog.csdn.net/weixin_47529865/article/details/112208721
1.4