牛客小白赛 / leetcode双周赛:

知识点总结:

1.__builtin_popcount(r),算数字里有几个1

class Solution {
public:
  vector<int> sortByBits(vector<int>& arr) {
    sort(arr.begin(), arr.end(), [](int l, int r) {
      int ln = __builtin_popcount(l);
      int rn = __builtin_popcount(r);
      if (ln != rn) return ln < rn;
      return l < r;
    });
   return arr;
  }
};

2.若直接计算数字中1的个数,可以用取余,除法来算

3.在类外直接写比较函数,加const &

4.第三题题解

后面的题不要抱有幻想,一定要用DP DFS/BFS之类的做,不要尝试暴力  

1358. Number of Substrings Containing All Three Characters

Given a string s consisting only of characters ab and c.

Return the number of substrings containing at least one occurrence of all these characters ab and c.

 

Example 1:

Input: s = "abcabc"
Output: 10
Explanation: The substrings containing at least one occurrence of the characters ab and c are "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc" and "abc" (again). 

Example 2:

Input: s = "aaacb"
Output: 3
Explanation: The substrings containing at least one occurrence of the characters ab and c are "aaacb", "aacb" and "acb".

Example 3:

Input: s = "abc"
Output: 1

 

Constraints:

  • 3 <= s.length <= 5 x 10^4
  • s only consists of ab or characters
//sequence "abcabc" find substring contain 'a','b','c'
class Solution {
public:
    int numberOfSubstrings(string s) {
        int n = s.size();
        //two-dimension vector store range
        vector<vector<int> > dp(3, vector<int>(n + 1, -1));
        //store the nearest index of appearance a b c
        for (int i = n - 1; i >= 0; i--) {
            //no new appear record past
            for (int j = 0; j < 3; j++) dp[j][i] = dp[j][i + 1];
            //has new flush
            dp[s[i] - 'a'][i] = i;
        }
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            bool ok = true;
            //if has -1 means lack of val
            for (int j = 0; j < 3; j++) {
                if (dp[j][i] == -1) ok = false;
            }
            //if ensure have three kinds calc the max distance to end
            if (ok) {
                int mx = -1;
                for (int j = 0; j < 3; j++) mx = max(mx, dp[j][i]);
                ans += n - mx;
            }
        }
        return ans;
    }
};

判断两个日期之间的距离:

这道是旧题,繁琐,与之前钟表算时差的类似。直接计算两个年份不好算。

所以应该把0年0月0日定为起始点。python有本身的函数可以调用,好计算特别多

闰年判断也很繁琐:

核心思路是能被4和100整除的,必须能被400整除,或者只能被4整除都是闰年

简洁解法:PS因为没用map而是数组,所以下标直接从0开始,结尾也得相应提前。所有循环,下标都有的问题是从0/1开始,更注意的是the end also be m/m-1. if not m-1 below the answer will have a few days(1-2) differ with answer,because both add wrong month.so the difference not appearance in the val they get from function but in the month different.

 

class Solution {
    bool leap(int year)
    {
        //简洁的用法判断闰年
        return year%4==0&&(year%100!=0||year%400==0);
    }
    int day(int y,int m,int d)
    {
        //int数组就能解决,{}初始化,?:筛选并改变2月数值
        int md[12]={31,leap(y)?29:28,31,30,31,30,31,31,30,31,30,31};
        int r=0;
        //divide two part represent,1970 from question definition
        for(int i=1970;i<y;++i)
            r+=leap(i)?366:365;
        //index not represent month so from 0 just to count correct time,becasue from 0,m also need -1
        for(int j=0;j<m-1;++j)
            r+=md[j];
        //assign combine return simplify operations
        return r+=d;
    }
    
public:
    int daysBetweenDates(string date1, string date2) {
        int y1=stoi(date1.substr(0,4)),m1=stoi(date1.substr(5,2)),d1=stoi(date1.substr(8,2));
        int y2=stoi(date2.substr(0,4)),m2=stoi(date2.substr(5,2)),d2=stoi(date2.substr(8,2));
        return abs(day(y1,m1,d1)-day(y2,m2,d2));
    }
};

 

 

 

BONUS:

string和int/double等类型互相转化:

转为string用to_string()大一统

转为int用stoi

stoi(s,p,b)、stol(s,p,b)、stod(s,p,b)等转换函数,可以函数,可以分别转化成int、long、double等.

stoi(string<可以只是一部分>,size_type<记录string的有效长度,遇到空格会被分隔开>,进制<从哪个进制转成10进制的数>)

使用示例:

 

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
//C++中还是多用cstring
int main()
{
    string a="123456789";
    //atoi函数把char数组转成int
    char a1[20];
    char str[] = "123456789";
    //strcpy返回值是char
    strcpy(a1,"23445");
    int i=atoi(a1);
    //在C++中应多用stoi,string直接转化
    //size_t* t=2;
    string tt="12";
    std::string::size_type sz=4;
    int a2=stoi(a,&sz,10);
    cout<<sz<<endl;
    cout<<a2<<endl;
    int a3=stoi(&a[1]);
//    cout<<a3<<endl;
    return 0;
}

 

 

 

#include<iostream>
#include<cstring>
using namespace std;
//C++中还是多用cstring
int main()
{
    string a="23456";
    //atoi函数把char数组转成int
    char a1[20];
    //strcpy返回值是char*
    strcpy(a1,"23445");
    int i=atoi(a1);
    //在C++中应多用stoi,string直接转化
    int a1=stoi(a);
    cout<<i<<endl;
    return 0;
}

 

 

onstraints:

  • 3 <= s.length <= 5 x 10^4
  • s only consists of ab or characters.
//sequence "abcabc" find substring contain 'a','b','c'
class Solution {
public:
    int numberOfSubstrings(string s) {
        int n = s.size();
        //two-dimension vector store range
        vector<vector<int> > dp(3, vector<int>(n + 1, -1));
        //store the nearest index of appearance a b c
        for (int i = n - 1; i >= 0; i--) {
            //no new appear record past
            for (int j = 0; j < 3; j++) dp[j][i] = dp[j][i + 1];
            //has new flush
            dp[s[i] - 'a'][i] = i;
        }
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            bool ok = true;
            //if has -1 means lack of val
            for (int j = 0; j < 3; j++) {
                if (dp[j][i] == -1) ok = false;
            }
            //if ensure have three kinds calc the max distance to end
            if (ok) {
                int mx = -1;
                for (int j = 0; j < 3; j++) mx = max(mx, dp[j][i]);
                ans += n - mx;
            }
        }
        return ans;
    }
};

posted on 2020-02-23 10:23  黑暗尽头的超音速炬火  阅读(242)  评论(0)    收藏  举报