新专栏,预计两个月写完吧,每天下班回来抽空做几道题。会把做题计划顺序记录下来,如果你有缘,刷到这个开篇序列,那就跟着文章去练题吧。初学者可以慢慢来
void merge(vector& nums1, int m, vector& nums2, int n) {
int i=m-1;
int j=n-1;
int k=m+n-1;
//从后往前插
while(j>=0)
{
if(i>=0&&nums1[i]>nums2[j])
{
nums1[k--]=nums1[i];
i--;
}
else{
nums1[k--]=nums2[j];
j--;
}
}
}
这是前后指针覆盖做的,也可以双向指针交换做,思路 i从0开始,j从尾巴开始,如果i的值不等于val那就++,如果等于了就和j的值交换,j--,i不变,下一轮再交换来的i还是不是val,是的话继续交换,j--,这样循环
int removeElement(vector& nums, int val) {
int i=0,j=0;
while(j
int removeDuplicates(vector& nums) {
int i=0,j=0;
while(j
int removeDuplicates(vector& nums) {
int i=0,j=0;
while(j
方法太多了,我写三个就行
int majorityElement(vector& nums) {
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
}
int majorityElement(vector& nums) {
unordered_mapmp;
int ans=0;
for(const auto &x:nums)
{
mp[x]++;
if(mp[x]>nums.size()/2){
ans=x;
}
}
return ans;
}
摩尔投票法只满足超过一半的投票,符合题意
玩的就是票数抵消,留下存活的那个
int majorityElement(vector& nums) {
//摩尔投票法,一种很奇妙的思路
int candition=0;//候选人
int vote=0;//票数
for(auto x:nums)
{
if(vote==0)candition=x;
if(x==candition)vote++;
if(x!=candition)vote--;
}
return candition;
}
第一句为了防止越界,这力扣限制服了,,写了两种方法
void rotate(vector& nums, int k) {
k%=nums.size();
vectorvv;
vv.reserve(nums.size()*2);
vv.insert(vv.end(),nums.begin(),nums.end());
vv.insert(vv.end(),nums.begin(),nums.end());
vectorvp(vv.begin()+nums.size()-k,vv.begin()+nums.size()*2-k);
nums=vp;
}
void rotate(vector& nums, int k) {
k%=nums.size();
reverse(nums.begin(),nums.begin()+nums.size()-k);
reverse(nums.begin()+nums.size()-k,nums.end());
reverse(nums.begin(),nums.end());
}
int maxProfit(vector& prices) {
vector>dp(prices.size(),vector(2));
dp[0][0]=-prices[0]; //有股票
dp[0][1]=0; //没有股票
for(int i=1;i
int maxProfit(vector& prices) {
//0 手里没股票 ,1手里有股票
vector>dp(prices.size(),vector(2));
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i
只要范围覆盖能到就行
bool canJump(vector& nums) {
int n=nums.size()-1;
int cover=0;
for(int i=0;i<=cover;++i)
{
cover=max(nums[i]+i,cover);
if(cover>=n){
return true;
}
}
return false;
}
int jump(vector& nums) {
if(nums.size()==1){
return 0;
}
int n=nums.size()-1;
int cover=0;
int ans=0;
int cur=0;
for(int i=0;i=n)
{
break;
}
}
}
return ans;
}
int hIndex(vector& citations) {
//默认h为文章数,对引用量排序,如果小于h,将h--。
int lens=citations.size();
if(lens==0){
return 0;
}
int h=lens;
sort(citations.begin(),citations.end());
for(auto x:citations){
if(x
用vector的下标和map做映射
class RandomizedSet {
private:
vectorvv;
unordered_mapmp; //key->val vaule->index
public:
RandomizedSet() {
srand((unsigned int)time(NULL));
}
bool insert(int val) {
if(mp.count(val)){
return false;
}
int idx=vv.size();
mp[val]=idx;
vv.push_back(val);
return true;
}
bool remove(int val) {
if(!mp.count(val)){
return false;
}
int preidx=mp[val];
int curidx=vv.size()-1;
vv[preidx]=vv[curidx];
//更新map 对应下标
mp[vv[preidx]]=preidx;
//删除
vv.pop_back();
mp.erase(val);
return true;
}
int getRandom() {
int idx=rand()%vv.size();
return vv[idx];
}
};
vector productExceptSelf(vector& nums) {
//左乘积 * 右乘积
int ml=1;
vectorvv(nums.size(),1);
for(int i=1;i=0;--i)
{
mr*=nums[i+1];
vv[i]*=mr;
}
return vv;
}
int canCompleteCircuit(vector& gas, vector& cost) {
/* if(accumulate(gas.begin(),gas.end(),0)
int candy(vector& ratings) {
//每个孩子都至少有一个糖果
vectorres(ratings.size(),1);
//从前往后,把右边分数高的糖果多一个
for(int i=0;i0;--i)
{
if(ratings[i-1]>ratings[i])
{
res[i-1]=max(res[i-1],res[i]+1);
}
}
return accumulate(res.begin(),res.end(),0);
}
我有篇博客详细讲了这个题的做法,用了五种方法
这块我演示三种推荐的
找到最高点,左右两边,求雨水
int trap(vector& height) {
int ans=0;
int value=0;
int index=0;
for(int i=0;ivalue){
value=height[i];
index=i;
}
}
int st=0;
for(int i=0;ist){
st=height[i];
}
else{
ans+=st-height[i];
}
}
st=0;
for(int i=height.size()-1;i>index;--i)
{
if(height[i]>st){
st=height[i];
}
else{
ans+=st-height[i];
}
}
return ans;
}
双指针
int trap(vector& height) {
int left=0;
int right=height.size()-1;
int ans=0;
int mlhi=height[0];
int rlhi=height[height.size()-1];
while(leftrlhi){
ans+=rlhi-height[right];
right--;
}
else{
ans+=mlhi-height[left];
left++;
}
}
return ans;
}
单调栈 递减
int trap(vector& height) {
stacksk;
sk.push(0);
int ans=0;
for(int i=1;iheight[sk.top()])
{
int righthright=height[i];
int curheight=height[sk.top()];
sk.pop();
if(!sk.empty())
{
int leftheight=height[sk.top()];
int chang=i-sk.top()-1;
int gao=min(righthright,leftheight)-curheight;
ans+=chang*gao;
}
}
sk.push(i);
}
return ans;
}
int romanToInt(string s) {
int res=0;
for(int i=0;i
string intToRoman(int num) {
//哈希
int arr[]{1000,900,500,400,100,90,50,40,10,9,5,4,1};
string btr[]{"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
string ans="";
for(int i=0;i=arr[i])
{
num-=arr[i];
ans+=btr[i];
}
}
return ans;
}
int lengthOfLastWord(string s) {
int count=0;
int i=s.size()-1;
for(i;i>=0;)
{
if(count&&s[i]==' ')
{
break;
}
if(s[i]==' ')
{
i--;
}
else{
count++;
i--;
}
}
return count;
}
学习minmax_element
string longestCommonPrefix(vector& strs) {
if(strs.empty())return "";
auto p=minmax_element(strs.begin(),strs.end());
for(int i=0;isize();++i)
{
if(p.first->at(i)!=p.second->at(i))
{
return p.first->substr(0,i);
}
}
return *p.first;
}
string longestCommonPrefix(vector& strs) {
//纵向对比,横向去扫描
//abcf
//ab
//abs
if(strs.empty()){
return "";
}
string res="";
for(int j=0;j
直接重构字符串,,不用erase去写了,erase版本好麻烦写起来
string reverseWords(string s) {
//重构字符串,去重多余空格
int slow=0;
for(int i=0;i
string convert(string s, int numRows) {
string res="";
if(numRows==1)return s;
vectorvv(numRows);
int k=0;
int flg=1;//标志转向
for(int i=0;i0?-1:1;
}
for(auto x:vv)
{
res+=x;
}
return res;
}
要用kmp。麻烦,
暴力解法:
int strStr(string haystack, string needle) {
if(haystack.size()
kmp: 面试的时候要是面试官让你去写kmp,就把屎盆子扣他脑门,,看着代码感觉不多,思想是极其巧妙的,很难理解,而且稍微一变形,你会难的你根本不知道用kmp从何下手,Knuth-Morris-Pratt 三兄弟,花了若干年研究的成果,在网上各路大神眼里,居然是个简单算法。。。
总之除非你把kmp理解的非常非常清楚,随便一个类型题就就能在15分钟内靠理解的kmp搞出来,那你可以去申请图灵奖了
反正我是每次写到这题就是暴力,然后看看kmp题解,看懂一次 过几天就忘了
void ex(int *arr,const string&needle)
{
int j=0;
arr[0]=j;
for(int i=1;i0&&needle[j]!=needle[i])
{
j=arr[j-1];
}
if(needle[i]==needle[j])
{
j++;
}
arr[i]=j;
}
}
int strStr(string haystack, string needle) {
if(needle.size()==0)
{
return -1;
}
int arr[needle.size()];
ex(arr,needle);
int j=0;
for(int i=0;i0&&haystack[i]!=needle[j]) //回退
{
j=arr[j-1];
}
if(haystack[i]==needle[j])
{
j++;
}
if(j==needle.size())
{
return i-needle.size()+1;
}
}
return -1;
}