2019年5月31日 第四天练习(13罗马数字转整数)+2019年6月3日 第五天练习(14最长公共前缀)

13.罗马数字转整数

题目的大致意思就是将罗马数字转换成对应的整数。我的想法是依次读出字符,然后变成相应的数字就ok了,但这里有一个难点是如何进行”小数位置在大数左边“这种行为的处理?
解决方法
要不一次读取两个字符,如果左边字符小于右边字符,则只输出左边字符,若左边字符大于右边字符,则二者一起输出。
首先要解决的是如何一次读取两个字符?
方法一: 还是用字符串的数组来判断

class Solution {
public:
    int romanToInt(string s) {
        int sum = 0;
        for(int i = 0; i < s.size(); ++i)
        {
            if(s[i] == 'I')
            {
                if(i != s.size() - 1 && (s[i+1] == 'V' || s[i+1] == 'X'))
                {
                    sum -= 1;
                }
                else
                    sum += 1;
            }
                
            if(s[i] == 'V')
                sum += 5;
            if(s[i] == 'X')
            {
                if(i != s.size() - 1 && (s[i+1] == 'L' || s[i+1] == 'C'))
                {
                    sum -= 10;
                }
                else
                    sum += 10;
            }
            if(s[i] == 'L')
                sum += 50;
            if(s[i] == 'C')
            {
                if(i != s.size() - 1 && (s[i+1] == 'D' || s[i+1] == 'M'))
                {
                    sum -= 100;
                }
                else
                    sum += 100;
            }
            if(s[i] == 'D')
                sum += 500;
            if(s[i] == 'M')
                sum += 1000;
        }
        return sum;
        
    }
};

执行后:
在这里插入图片描述

方法二 调用string中的一个函数方法substr()进行实现,这样可以实现一次读取两个字符。

string substr (size_t pos = 0, size_t len = npos) const
主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度或超出了源字符串的长度,则子字符串将延续到源字符串的结尾。

所以实现的代码如下:

class Solution {
public:
    int romanToInt(string s) 
    {
        if(s=="")
            return 0;
        int sum=0;
        int len=s.size();
        int i=0;
        while(i<len)
        {
            if(s.substr(i,2)=="IV")
            {
                sum=sum+4;
                i=i+2;
                continue;
            }
            if(s.substr(i,2)=="IX")
            {
                sum=sum+9;
                i=i+2;
                continue;
            }
            if(s.substr(i,2)=="XL")
            {
                sum=sum+40;
                i=i+2;
                continue;
            }
            if(s.substr(i,2)=="XC")
            {
                sum=sum+90;
                i=i+2;
                continue;
            }
            if(s.substr(i,2)=="CD")
            {
                sum=sum+400;
                i=i+2;
                continue;
            }
            if(s.substr(i,2)=="CM")
            {
                sum=sum+900;
                i=i+2;
                continue;
            }
            if(s.substr(i,1)=="I")
            {
                sum=sum+1;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="V")
            {
                sum=sum+5;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="X")
            {
                sum=sum+10;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="L")
            {
                sum=sum+50;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="C")
            {
                sum=sum+100;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="D")
            {
                sum=sum+500;
                i=i+1;
                continue;
            }
            if(s.substr(i,1)=="M")
            {
                sum=sum+1000;
                i=i+1;
                continue;
            }

        }

       return sum; 
    }
};

执行后:发现调用函数并不如直接用数组进行执行的效率更高些
在这里插入图片描述
后来看到别人的代码,发现在C++语言中用哈希算法构造对应关系也可以完成,比如某位大神写的

class Solution {
public:
    int romanToInt(string s) {
        int result=0;
        map<char,int> myMap;
        myMap.insert(map<char,int>::value_type('I',1));
        myMap.insert(map<char,int>::value_type('V',5));
        myMap.insert(map<char,int>::value_type('X',10));
        myMap.insert(map<char,int>::value_type('L',50));
        myMap.insert(map<char,int>::value_type('C',100));
        myMap.insert(map<char,int>::value_type('D',500));
        myMap.insert(map<char,int>::value_type('M',1000));
        for(int i=0;i<s.length();i++){
            if(myMap[s[i]]>=myMap[s[i+1]])
                result+=myMap[s[i]];
            else{
                result+=myMap[s[i+1]]-myMap[s[i]];
                i++;
            }
 
        }
        return result;
        
    }
};

但这个效率…函数用的太多的过,但代码简洁,易于增长
在这里插入图片描述

14 最长公共前缀

首先忏悔,六月一日二日过儿童节太快乐了,不仅导致31日的没有发出去还耽误了两天没有写…我忏悔==。但6.1日还顺便考了个试,EMMMM考的人工智能的一个训练营,突然发现要学机器学习和人工智能,是很要数学功底的啊啊啊啊,照样是题都看不懂,不说了都是泪,继续好好刷题吧…

今天继续刷easy类的题,这道题的大致意思就是数组里存几个字符串,判断这些字符串的公共前缀是什么。

好吧,看到第一眼毫无思路,觉得是要一个字符一个字符拿出来比较,总不能有几个字符串建立几个栈或者指针吧==。

看了答案,果然不是,有以下几种思路(因为不会,只能照搬了,学习了)

方法一:水平扫描法
首先,我们将描述一种查找一组字符串的最长公共前缀 LCP(S1…Sn)的简单方法我们将会用到这样的结论:
LCP(S1…Sn)=LCP(LCP(LCP(S 1​,S2​),S3​),…S n​ )

我个人感觉这个方法很容易理解,而且也很容易实现,所以用代码敲一敲试试:

    class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
       if(strs.empty()) return"";
        string s=strs[0];
        for(int i=1;i<strs.size();i++){ //要注意数组中只有size()方法,没有length()方法。
            for(int j=0;j<s.length();j++){
                if(s[j]==strs[i][j])
                    continue;
                else{
                    s.erase(j);
                    break;
                }
            }
        }
        return s;
        
    }
};

在这里插入图片描述

方法二:水平扫描
想象数组的末尾有一个非常短的字符串,使用方法一依旧会进行S​ 次比较。优化这类情况的一种方法就是水平扫描。我们从前往后枚举字符串的每一列,先比较每个字符串相同列上的字符(即不同字符串相同下标的字符)然后再进行对下一列的比较。

  class Solution {   
    public:
        string longestCommonPrefix(vector<string>& strs) {
        if (strs.empty()) return "";
        for (int i = 0; i < strs[0].length() ; i++){
            char c = strs[0].at(i);
            for (int j = 1; j < strs.size(); j ++) {
                if (i == strs[j].length() || strs[j].at(i) != c)
                    return strs[0].substr(0, i); 
                     }
                 }
        return strs[0];
         }
    };

可以看到执行用时以最短的字符串为标准,执行时间大大减少,但是若字符串长度相等,则这个方法效率并不会很明显。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值