剑指offer 第二版(1——20)

 剑指 Offer II 001. 整数除法

 int divide(int a, int b) {
        bool flag=false;
        if(b==INT_MAX){
            if(a==INT_MIN||a==-INT_MAX) return -1;
            if(a==INT_MAX) return 1;
            else return 0;
        } 
        if(b==INT_MIN) {
            if(a==INT_MIN) return 1;
            else return 0;
        }
        if(a==INT_MAX){
            if(b==INT_MAX) return 1;
            if(b==1) return a;
            if(b==-1) return -a;
        } 
        if(a==INT_MIN) {
            if(b==INT_MIN) return 1;
            if(b==1) return a;
            if(b==-1) return pow(2,31)-1;
        }
        if((a<0&&b<0)||(a>0&&b>0)) flag=true;
        else flag=false;
        if(a==0) return 0;
        if(a==b) return 1;

        long aa=abs(a),ja=abs(a) ,jb=abs(b),bb=abs(b);

        long cnt=1;
        int scnt=cnt,sbb=bb;
        while(bb<aa){
            scnt=cnt;sbb=bb;
            bb+=bb ,cnt+=cnt;
        } 
        cnt=scnt;bb=sbb;
        while(bb<=aa) bb+=jb,cnt++;
        if(flag){
            if(cnt-1>pow(2,31)-1) return pow(2,31)-1;
            return cnt-1;
        } 
        else{
            return -(cnt-1);
        } 
    }

 剑指 Offer II 002. 二进制加法

 string addBinary(string a, string b) {
        if(a.size()<b.size()) swap(a,b);
        string res;
        vector<int> aa(a.size(),0),bb(a.size(),0);
        for(int i=a.size()-1,j=0;i>=0;i--,j++) aa[j]=a[i]-'0';
        for(int i=b.size()-1,j=0;i>=0;i--,j++) bb[j]=b[i]-'0';

        int cnt=0;
        for(int i=0;i<a.size();i++){
            int ans=aa[i]+bb[i]+cnt;
            cnt=0;
            if(ans==0) res+='0';
            if(ans==1) res+='1';
            if(ans==2) res+='0',cnt++;
            if(ans==3) res+='1',cnt++;
        }
        if(cnt) res+='1';
        reverse(res.begin(),res.end());
        return res;
    }

 剑指 Offer II 003. 前 n 个数字二进制中 1 的个数

 位运算:

 int lowbit(int n){
        return n&-n;//返回最后一个1例如:10->1010 返回2。
    }
    vector<int> countBits(int n) {
        vector<int> res;
        for(int i=0;i<=n;i++){
            int cnt=0;
            int kk=i;
            while(kk) cnt++,kk-=lowbit(kk);
            res.push_back(cnt);
        }
        return res;
    }

 dp:偶数的1的个数等于偶数/2的个数,奇数的个数等于上一个偶数的个数+1;

 vector<int> countBits(int n) {
        vector<int> res(n,0);
        res.push_back(0);
        for(int i=1;i<=n;i++){
            if(i%2==1) res[i]=res[i-1]+1;
            else res[i]=res[i/2];
        }
        return res;
    }

 剑指 Offer II 004. 只出现一次的数字 

 int singleNumber(vector<int>& nums) {
        unordered_map<int ,int> map;
        for(int i=0;i<nums.size();i++) map[nums[i]]++;

        for(auto cc:map){
            if(cc.second==1) return cc.first;
        }
        return 0;
    }

剑指 Offer II 005. 单词长度的最大乘积

 int maxProduct(vector<string>& words) {
        int res=0;
        int f[words.size()][26];
        memset(f,0,sizeof(f));
        for(int i=0;i<words.size();i++){
            for(int j=0;j<words[i].size();j++){
                f[i][words[i][j]-'a']=1;
            }
        }
        for(int i=0;i<words.size();i++){
            for(int j=i+1;j<words.size();j++){
                bool flag= true;
                for(int k=0;k<words[j].size();k++){
                    if(f[i][words[j][k]-'a']!=0) {
                        flag=false;
                        break;
                    }
                } 
                int xx=  words[i].size()*words[j].size();  
                if(flag) res=max(res,xx);
            }
        }
        return res;
    }

 剑指 Offer II 006. 排序数组中两个数字之和

vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        for(int i=0,j=nums.size()-1;i<nums.size();i++){
            while(j>i&&nums[i]+nums[j]>target) j--;
            if(nums[i]+nums[j]==target){
                res.push_back(i),res.push_back(j);
                break;
            } 
        }
        return res;
    }

 剑指 Offer II 007. 数组中和为 0 的三个数

vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());

        for(int i=0;i<nums.size();i++){
            if(i&&nums[i]==nums[i-1]) continue;
           for(int j=i+1,k=nums.size()-1;j<k;j++){
               if(j!=i+1&&nums[j]==nums[j-1]) continue;
               while(k>j&&nums[i]+nums[j]+nums[k]>0) k--;
               if(k>j&&nums[i]+nums[j]+nums[k]==0){
                   vector<int> xx;
                   xx.push_back(nums[i]),xx.push_back(nums[j]),xx.push_back(nums[k]);
                   res.push_back(xx);
               }
           }
        }
        //res.erase(unique(res.begin(),res.end()),res.end());
        return res;
    }

剑指 Offer II 008. 和大于等于 target 的最短子数组

 滑动窗口优化版:

int minSubArrayLen(int target, vector<int>& nums) {
        int res=INT_MAX;
        int sum=nums[0];
        if(nums[0]>=target) return 1;
        for(int i=0,j=1;i<nums.size();){
            while(j<nums.size()&&sum<target) sum+=nums[j],j++;
            if(j<=nums.size()&&sum>=target)  res=min(res,j-i),sum-=nums[i],i++;
            if(j==nums.size()&&sum<target) break;
        }
        if(res==INT_MAX) return 0;
        return res;
    }

 剑指 Offer II 009. 乘积小于 K 的子数组

 int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        int res=0,p=1;
        for(int i=0,j=0;j<nums.size();j++){
            p*=nums[j];
            while(i<=j&&p>=k) p/=nums[i++];
            res+=j-i+1;
        }
        return res;
    }

 剑指 Offer II 010. 和为 k 的子数组

int subarraySum(vector<int>& nums, int k) {
        unordered_map<int,vector<int>>map;
        int res=0;
        int sum[nums.size()];
        sum[0]=nums[0];
        if(nums[0]==k) res++;
        map[sum[0]].push_back(0);
        for(int i=1;i<nums.size();i++){
            sum[i]=sum[i-1]+nums[i];
            if(sum[i]==k) res++;
            map[sum[i]].push_back(i);
        } 
        
        for(int i=0;i<nums.size();i++){
          //  if(k==0)
           vector<int>xx= map[sum[i]-k];
            if(!xx.empty()){
                for(int j=0;j<xx.size();j++){
                    if(xx[j]<i){
                        res++;
                    } 
                }
            }   
        }
        return res;
    }   

剑指 Offer II 011. 0 和 1 个数相同的子数组

int findMaxLength(vector<int>& nums) {
        int s[nums.size()+1];
        unordered_map<int,int>map;
        int res=0;
        map[0]=0;
        for(int i=1,one=0,zero=0;i<=nums.size();i++){
            if(nums[i-1]==1) one++;
            else zero++;
            int s=one-zero;
            if(map.count(s)!=0) res=max(res,i-map[s]);
            else map[s]=i; 
        }
        return res;
    }

剑指 Offer II 012. 左右两边子数组的和相等

int pivotIndex(vector<int>& nums) {
        int n=nums.size();
        int s[nums.size()];
        s[0]=nums[0];
        for(int i=1;i<n;i++) s[i]=nums[i]+s[i-1];

        for(int i=0;i<nums.size();i++){
            int suml=0,sumr=0;
            if(i) suml=s[i-1];
            if(i<nums.size()) sumr=s[n-1]-s[i];
            if(suml==sumr) return i;
        }
        return -1;
    }

剑指 Offer II 013. 二维子矩阵的和

 int sum[200][200];
    NumMatrix(vector<vector<int>>& matrix) {
        memset(sum,0,sizeof(sum));
        sum[0][0]=matrix[0][0];
        for(int i=0;i<matrix.size();i++){
            for(int j=0;j<matrix[i].size();j++){
               if(i&&j) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+matrix[i][j];
               else if(i&&!j) sum[i][j]=sum[i-1][j]+matrix[i][j];
               else if(!i&&j) sum[i][j]=sum[i][j-1]+matrix[i][j];
            }
        }
    }
    
    int sumRegion(int row1, int col1, int row2, int col2) {
        if(col1&&row1)
        return sum[row2][col2]-sum[row2][col1-1]-sum[row1-1][col2]+sum[row1-1][col1-1];
        else if(col1&&!row1)
        return sum[row2][col2]-sum[row2][col1-1];
        else if(!col1&&row1)
        return sum[row2][col2]-sum[row1-1][col2];
        else return sum[row2][col2];
    }

 剑指 Offer II 014. 字符串中的变位词

 bool checkInclusion(string s1, string s2) {
        unordered_map<char,int>map;
        long cnt=0;
        for(int i=0;i<s1.size();i++){
            cnt+=(s1[i])*(s1[i])*13;
            map[s1[i]]++;
        } 
        for(int i=0;i<s2.size();i++){
            if(map[s2[i]]!=0){
                string str=s2.substr(i,s1.size());
                long sum=0;
                for(int j=0;j<str.size();j++){
                    sum+=((int)str[j])*((int)str[j])*13;
                } 
                if(cnt==sum) return true;
            }
        }
        return false;
    }

 滑动窗口优化后(基本双百):

bool checkInclusion(string s1, string s2) {
        int f[26]={0};
        for(int i=0;i<s1.size();i++) f[s1[i]-'a']--;

        for(int i=0,j=0;j<s2.size();j++){
            int idx=s2[j]-'a';
            f[idx]++;
            while(i<=j&&f[idx]>0) --f[s2[i]-'a'], i++;
            if(j-i+1==s1.size()) return true;
        }
        return false;
    }

剑指 Offer II 015. 字符串中的所有变位词

vector<int> findAnagrams(string s, string p) {
        vector<int> res;
        int f[26];
        //memset(f,0,sizeof(f));
       
        int sz=s.size(),pz=p.size();
        for(int i=0;i<pz;i++) f[p[i]-'a']--;

        for(int i=0,j=0;j<sz;j++){
            f[s[j]-'a']++;
            while(i<=j&&f[s[j]-'a']>0) --f[s[i]-'a'],i++;
            if(j-i+1==pz) res.push_back(i); 
        }
        return res;
    }

 剑指 Offer II 016. 不含重复字符的最长子字符串

int lengthOfLongestSubstring(string s) {
        if(s.size()==0) return 0;
        int f[200];
        int res=0;
        memset(f,0,sizeof(f));
        for(int i=0,j=0;j<s.size();j++){
            f[s[j]]++;
            while(i<=j&&f[s[j]]>1) --f[s[i]],i++;
            res=max(res,j-i+1);
        }
        return res;
    }

剑指 Offer II 017. 含有所有字符的最短字符串

string minWindow(string s, string t) {
        set <char>st;
        unordered_map<char,int> map1,map2;

        for(int i=0;i<t.size();i++) st.insert(t[i]),map1[t[i]]++;

        int res=INT_MAX,l=0,r=0;
        int cnt=0;
        for(int i=0,j=0;j<s.size();j++){
            map2[s[j]]++;
            if(map1.count(s[j])&&map2[s[j]]==map1[s[j]]) cnt++;
            
            while(i<=j&&cnt==st.size()){
                if(res>j-i+1){
                    res=j-i+1;
                    l=i,r=j;
                }
                --map2[s[i]];
                if(map1.count(s[i])&&map2[s[i]]+1==map1[s[i]]){
                    cnt--;
                } 
                i++;
            } 
        }
        if(res==INT_MAX) return "";
        return s.substr(l,r-l+1);
    }

剑指 Offer II 018. 有效的回文

bool isPalindrome(string s) {
        if(s.size()<=1) return true;
        string str;
        for(int i=0;i<s.size();i++){
            if(s[i]>='a'&&s[i]<='z') str+=s[i];
            if(s[i]>='0'&&s[i]<='9') str+=s[i];
            if(s[i]>='A'&&s[i]<='Z') str+=(s[i]+32);
        }
        for(int i=0;i<=str.size()/2;i++){
            if(str.size()==0)break;
            if(str[i]!=str[str.size()-1-i])  return false;
        }
        return true;
    }

 剑指 Offer II 019. 最多删除一个字符得到回文

 bool check(string str){
        for(int i=0;i<=str.size()/2;i++){
            if(str[i]!=str[str.size()-i-1]) return false;
        }
        return true;
    }
    bool validPalindrome(string s) {
        int l=0,r=0;
        bool flag=true;
        for(int i=0,j=s.size()-1;i<=s.size()/2;i++,j--){
            if(s[i]!=s[j]){
                l=i;r=j;
                flag=false;
                break;
            } 
        }
        if(flag) return true;
        int len=s.size();
        string str1=s.substr(0,l)+s.substr(l+1,len-(l+1)+1);
        string str2=s.substr(0,r)+s.substr(r+1,len-(r+1)+1);
        if(check(str1)||check(str2)) return true;
        else return false; 
    }

 剑指 Offer II 020. 回文子字符串的个数

 int countSubstrings(string s) {
        bool f[1010][1010];
        memset(f,false,sizeof(f));
        int res=0;
        int n=s.size();
        for(int i=n-1;i>=0;i--){
            for(int j=i;j<=n;j++){
                if(i==j) f[i][j]=true, res++;
                if(j-i==1&&s[i]==s[j])  f[i][j]=true,res++;
                if(j-i>1&&f[i+1][j-1]&&s[i]==s[j])f[i][j]=true, res++;
            }
        }
        return res;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值