20200715字节刷题准备(字符串的最大公因子,复原IP地址,乘积最大子数组)

本文介绍了三道编程题的解题思路:1) 字符串的最大公因子,通过找到能整除两个字符串长度的公约数来确定;2) 复原IP地址,利用递归分段法解决,需要判断每段数字的合法性;3) 乘积最大子数组,通过维护最大值和最小值来找到乘积最大的子数组。
摘要由CSDN通过智能技术生成
  1. 字符串的最大公因子
    其实就是对于两个字符串的长度 来取公约数 只要能当做两个整除的 就作为备选的
    然后一个一个看 按照这些每一个长度 截取到字符串的前几个字符 作为公因子 假如以他们来填充 是对的 那么作为res 遍历完备选的长度 就可以了
class Solution {
public:
    string gcdOfStrings(string str1, string str2) {
        vector<int>temp;
        int it;
        int len1=str1.size();
        int len2=str2.size();
        for(it=1;it<=str1.size() && it<=str2.size();it++){
            if(len1%it==0 && len2%it==0){
                temp.push_back(it);
            }
        }
        string res="";
        for(auto c:temp){
            string A,B;
            string le=str1.substr(0,c);
            for(int i=0;i<len1/c;i++){
                A+=le;
            }
            for(int j=0;j<len2/c;j++){
                B+=le;
            }
            if(str1==A && str2==B){
                res=le;
            }
        }
        return res;
    }
};
  1. 复原IP地址

解题思路:

IP地址由32位二进制数组成,为便于使用,常以XXX.XXX.XXX.XXX形式表现,每组XXX代表小于或等于255的10进制数。所以说IP地址总共有四段,每一段可能有一位,两位或者三位,范围是[0, 255],题目明确指出输入字符串只含有数字,所以当某段是三位时,我们要判断其是否越界(>255),还有一点很重要的是,当只有一位时,0可以成某一段,如果有两位或三位时,像 00, 01, 001, 011, 000等都是不合法的,所以我们还是需要有一个判定函数来判断某个字符串是否合法。

这道题其实也可以看做是字符串的分段问题,在输入字符串中加入三个点,将字符串分为四段,每一段必须合法,求所有可能的情况。根据目前刷了这么多题,得出了两个经验,一是只要遇到字符串的子序列或配准问题首先考虑动态规划DP,二是只要遇到需要求出所有可能情况首先考虑用递归。这道题并非是求字符串的子序列或配准问题,更符合第二种情况,所以我们要用递归来解。我们用k来表示当前还需要分的段数,如果k = 0,则表示三个点已经加入完成,四段已经形成,若这时字符串刚好为空,则将当前分好的结果保存。若k != 0, 则对于每一段,我们分别用一位,两位,三位来尝试,分别判断其合不合法,如果合法,则调用递归继续分剩下的字符串,最终和求出所有合法组合。

所以这道题需要用递归来做

class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        vector<string> res;
        helper(s, 0, "", res);
        return res;
    }
    void helper(string s, int n, string out, vector<string>& res) {
        if (n == 4) {
            if (s.empty()) res.push_back(out);
        } else {
            for (int k = 1; k < 4; ++k) {
                if (s.size() < k) break;
                int val = stoi(s.substr(0, k));
                if (val > 255 || k != std::to_string(val).size()) continue;
                helper(s.substr(k), n + 1, out + s.substr(0, k) + (n == 3 ? "" : "."), res);
            }
        }
    }
};

  1. 乘积最大子数组
    这道题的原理就是他同时维持最大值和最小值
    这两个值一旦遇到负数相乘 就交换
    否则 不断乘
class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int m_max=1;
        int m_min=1;
        int biggest=INT_MIN;
        for(int i=0;i<nums.size();i++){
            if(nums[i]<0){
                int temp=m_min;
                m_min=m_max;
                m_max=temp;
            }
            m_max=max(nums[i],m_max*nums[i]);
            m_min=min(nums[i],m_min*nums[i]);
            biggest=max(biggest,m_max);
        }
        return biggest;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值