输入一个正整数数组,把数组里所有的数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。这里自定义了一个排序规则。
class Solution { public: static int MyCompare(const string& s1,const string& s2){ return s1+s2<s2+s1; } string minNumber(vector<int>& nums) { int n=nums.size(); string ret; if(n==0) return ret; vector<string> strnums; for(auto i:nums){ strnums.push_back(to_string(i)); } sort(strnums.begin(),strnums.end(),MyCompare); for(auto i:strnums){ ret+=i; } return ret; } };
C的代码
#include<bits/stdc++.h> using namespace std; const int g_MaxNumberLength=10; char* g_strCombine1=new char[g_MaxNumberLength*2+1]; char* g_strCombine2=new char[g_MaxNumberLength*2+1]; int compare(const void* strNumber1, const void* strNumber2); void PrintMinNumber(int *numbers,int length){ if(numbers==nullptr||length<=0){ return; } char** strNumbers=(char**) (new int[length]); for(int i=0;i<length;++i){ strNumbers[i]=new char[g_MaxNumberLength+1]; sprintf(strNumbers[i],"%d",numbers[i]); } qsort(strNumbers,length,sizeof(char*),compare); for(int i=0;i<length;++i){ printf("%s",strNumbers[i]); } printf("\n"); for(int i=0;i<length;++i){ delete[] strNumbers[i]; } delete[] strNumbers; } int compare(const void* strNumber1, const void* strNumber2){ strcpy(g_strCombine1,*(const char**)strNumber1); strcat(g_strCombine1,*(const char**)strNumber2); strcpy(g_strCombine2,*(const char**)strNumber2); strcat(g_strCombine2,*(const char**)strNumber1); return strcmp(g_strCombine1,g_strCombine2); } int main(void) { int a[5]={3,30,34,5,9}; PrintMinNumber(a,5); return 0; }
2021年7月24日,还是要好好写笔记,好一阵没有认真做笔记记录了,有时候看看博客感觉自己写的题其实也不那么少了,但是长进却不大。
在网上看到的统计一个字符第一次和最后一次出现的位置的方法,最后一次的位置可以从后往前去算,加油加油,今天是学习的一天,下一周的周一到周四会在8:40到9点之间回家。
题目是这样的:字符串S由小写字母组成,我们要把这个字符串划分为尽可能多的片段,同一个字母最多出现在一个片段中,用的是贪心策略,思路是:需要统计出每个字符最后一次出现的位置,然后遍历该字符串
//统计某个字符第一次出现的位置 char* strchr(char *p,char a) { int i; assert(p!=NULL); for(i=0;i<strlen(p);i++) { if(p[i]==a) return p+i; } return 0; } //统计某个字符第一次出现的位置 char* strrchr(char *p,char a) { int i; char *ret=p; assert(p!=NULL); for(i=strlen(p)-1;i>0;i--) { if(p[i]==a) return ret+i; } return 0; }
反向迭代器:相比于正向迭代器只需要把begin和end换成rbegin和rend。关于unorder_map和map,我们希望可以是有序的(按照字母表索引的)可以使用map。不过这倒题目中,
直接使用下标操作存在一个危险的副作用:如果该键不在map容器中,那么下标操作会插入一个具有该键的新元素。但是大多数情况下,使用者并不想插入一个容器本不存在的key。
这道题目采取贪心策略,思路如下:
class Solution { public: vector<int> partitionLabels(string s) { int last[26]; vector<int> res; for(int i=0;i<s.size();++i){ last[s[i]-'a']=i; } int start=0, end=0; for(int i=0;i<s.size();++i){ if(last[s[i]-'a']>end){ end=last[s[i]-'a']; }//end=max(end,last[s[i-'a' ] if(i==end){ res.push_back(end-start+1); start=end+1; } } return res; } };
注意:不要忘记在while的分支里break
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。也可以延伸到多
个数组的多个指针。
若两个指针指向同一数组,遍历方向相同且不会相交,则也称为滑动窗口(两个指针包围的
区域即为当前的窗口),经常用于区间搜索。
若两个指针指向同一数组,但是遍历方向相反,则可以用来进行搜索,待搜索的数组往往是
排好序的。
一篇不错的题解:
注意这个最大的for循环是直到right超出了字符串s的范围
string s="ADOBECODEBANC"; string t="ABC"; vector<int> chars(128,0); vector<bool> flag(128,false); for(int i=0;i<t.size();++i){ flag[t[i]]=true; chars[t[i]]++; } int cnt = 0, left = 0, min_l = 0, min_size = s.size() + 1; for(int right=0;right<s.size();++right){ if(flag[s[right]]){//如果当前的字符是t中的字符,才有后面这一系列的 //--chars[s[right]];//碰到T中的字符就进行减 if(--chars[s[right]]>=0){ ++cnt;//找到了一个满足条件的字符;对于<0的结果不会去++cnt } cout<<"cnt="<<cnt<<endl; // 若目前滑动窗口已包含T中全部字符, // 则尝试将l右移, 在不影响结果的情况下获得最短子字符串 while(cnt==t.size()){ if(right-left+1<min_size){ min_size=right-left+1; min_l=left; cout<<"临时的min_size="<<min_size<<endl; } if(flag[s[left]] && ++chars[s[left]]>0){//这里写的有问题???chars的这个条件判断出错 //++chars[s[left]]; 一定注意这个条件, --cnt;//之前忘了写的 cout<<"--cnt="<<cnt<<endl; } ++left; cout<<"left="<<left<<endl; } } } cout<<"min_l="<<min_l<<" min_size="<<min_size<<endl; string res=min_size>s.size()? "":s.substr(min_l,min_size); cout<<"res="<<res; return 0;
输出的结果:这道题目要好好总结
此题不一样的是可以删除一个字符,这是一个变化点, 这是我第二次做的答案,执行用时好一些。注意flag的使用
class Solution { public: bool validPalindrome(string s) { int i=0, j=s.size()-1; int flag=0, temp; while(i<j){ if(s[i]==s[j]){ ++i; --j; } else{ flag++; break; } } int start, end; start=i; end=j; if(flag==1){ start++; while(start<end){ if(s[start]==s[end]){ ++start; --end; } else{ cout<<"--"<<endl; flag++; break; } } } if(flag==2){ start=i; end=j; --end; while(start<end){ if(s[start]==s[end]){ ++start; --end; } else{ flag++; break; } } } cout<<flag<<endl; if(flag==3){ return false; } else{ return true; } } };