刷题

1.分割回文
题目: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
第一步 动态规划判断是否为回文(长度为len的string s,从第 i 位到第 j 位是否是回文)
for(int i=len-1; i>=0; --i){
    for(int j=0; j<len; ++j){
        if(i>=j) dp[i][j] = true;
        else dp[i][j] = dp[i+1][j-1]&&s[i]==s[j];
    }
}
第二步  动态规划获取分割回文的最少次数
for(int i=1; i<len; ++i){
    if(dp[0][i]) {
        dpans[i] = 0;   //整体为回文 则为0
        continue;
    }
    dpans[i] = dpans[i-1];
    for(int j=i-1; j>0; --j){
        if(dp[j][i]){
            dpans[i] = min(dpans[i], dpans[j-1]);  //取从j-i是回文中左侧回文分割次数最小值 + 1
        }
    }
    dpans[i]++;
}
2. 有符号数和无符号数相减如果小于零  会出问题
例如  int k=5;  string s="123456789";
则 k - s.size() 则会出现bug, k为有符号数, s.size()为无符号数, 则 k - s.size() 结果为一个无符号的极大的数,不为-4,因为无符号数不会有负数。
3. 多数元素
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
int majorityElement(vector<int>& nums) {
        int candidate = -1;
        int count = 0;
        for (int num : nums) {
            if (num == candidate)
                ++count;
            else if (--count < 0) {
                candidate = num;
                count = 1;
            }
        }
        return candidate;
    }
相当于两个不同的数相互抵消,最后剩下的数必然是多数元素。
4. D天内送达货物的能力
传送带上的包裹必须在 days 天内从一个港口运送到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量(weights)的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 days 天内将传送带上的所有包裹送达的船的最低运载能力
int shipWithinDays(vector<int>& weights, int days) {  
//二分查找,最低运载里在[最大元素, 总和]之间,贪心得出该运载力时需要天数,并与需要天数比较,舍弃一半;
        int l = *max_element(weights.begin(), weights.end()), r = accumulate(weights.begin(), weights.end(), 0);
        while(l<r){
            int tem = (l+r)/2;
            int need = 1, sum_now = 0;
            for(auto weight:weights){
                sum_now += weight;
                if(sum_now>tem){
                    sum_now = weight;
                    need++;
                }
            }
            if(need>days) l=tem+1;
            else r = tem;
        }
        return l;
    }
5. 给定一个只包含三种字符的字符串:*,写一个函数来检验这个字符串是否为有效字符串。
bool checkValidString(string s) {
    int minleft = 0, maxleft = 0;
    for(auto it:s){
        if(it=='(') {
            minleft++;
            maxleft++;
        }else if(it=='*'){
            minleft = max(minleft-1, 0);
            maxleft++;
        }else{
            minleft = max(minleft-1, 0);
            maxleft--;
            if(maxleft<0) return false;
        }
    }
    return minleft==0;
}
6.最大矩形
给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;
        int m = matrix.size(), n = matrix[0].size();
        int ans = 0;
        vector<int> mat(n, 0);
        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){
                if(matrix[i][j]=='0'){
                    mat[j] = 0;
                }else{
                    ++mat[j];
                }
            }
            ans = max(ans, get(mat));
        }
        return ans;
    }
    int get(vector<int> mat){
        stack<int> sta;
        sta.push(-1);
        int ans = 0, i = 0, tem = 0;
        for(; i<mat.size(); ++i){
            while(sta.size()>1 && mat[sta.top()] > mat[i]){
                tem = mat[sta.top()];
                sta.pop();
                ans = max(ans, tem*(i-sta.top()-1));
            }
            sta.push(i);
        }
        while(sta.size()>1){
            tem = mat[sta.top()];
            sta.pop();
            ans = max(ans, tem*(i-sta.top()-1));
        }
        return ans;
    }
};
7. 最小的数
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
vector<int> singleNumber(vector<int>& nums) {
    int tem = 0;
    for(auto num:nums){
        tem ^= num;
    }
    tem = tem==INT_MIN ? tem : tem&(-tem);
    int n1 = 0, n2 = 0;
    for(auto num:nums){
        if(num&tem)
            n1 ^= num;
        else 
            n2 ^= num;
    } 
    return {n1, n2};
}
8.三等分
给定一个由 01 组成的数组 arr ,将数组分成 3 个非空的部分 ,使得所有这些部分表示相同的二进制值。
vector<int> threeEqualParts(vector<int>& arr) {
    int cntOne=accumulate(arr.begin(),arr.end(),0);
    if(cntOne%3!=0)return {-1,-1};
    if(cntOne==0)return {0,(int)arr.size()-1};
    cntOne/=3;
    int beg1=0,beg2=0,beg3=0;
    int curOneCnt=0;
    for(int i=0;i<arr.size();i++){
        if(curOneCnt==0)beg1=i;
        if(curOneCnt==cntOne)beg2=i;
        if(curOneCnt==cntOne*2)beg3=i;
        if(arr[i]==1){
            curOneCnt++;
        }
    }
    int subLen=arr.size()-beg3;
    for(int i=0;i<subLen;i++){
        if(arr[beg1+i]!=arr[beg2+i]||arr[beg1+i]!=arr[beg3+i])return {-1,-1};
    }
    return {beg1+subLen-1,beg2+subLen};
}
9. 计数质数
给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
int countPrimes(int n) {
    vector<int> isPrime(n, 1);
    int ans = 0;
    for (int i = 2; i < n; ++i) {
        if (isPrime[i]) {
            ans += 1;
            if ((long long)i * i < n) {
                for (int j = i * i; j < n; j += i) {
                    isPrime[j] = 0;
                }
            }
        }
    }
    return ans;
}







全部评论

相关推荐

03-29 15:34
门头沟学院 Java
北斗导航Compass低仿版:能不能先搞清楚优先级啊,怎么可能是项目问题,项目很重要吗?又没学历 又没实习大厂凭啥约面?那玩具项目 没应用在真实生产环境下的 就算做上天又有什么用?早点找个小公司实习 拿小公司实习去投大厂实习,这才是你现在该做的
投递美团等公司8个岗位 简历被挂麻了,求建议
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客企业服务