美文网首页
LeetCodeDay10

LeetCodeDay10

作者: GoMomi | 来源:发表于2018-04-19 13:06 被阅读0次

    38. 报数

    描述

    报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。

    前五项如下:
      1. 1
      2. 11
      3. 21
      4. 1211
      5. 111221
    其中:
      1 被读作  "one 1"  ("一个一") , 即 11。
      11 被读作 "two 1s" ("两个一"), 即 21。
      21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。
    给定一个正整数 n ,输出报数序列的第 n 项。
    
    注意
    • 整数顺序将表示为一个字符串。
    示例
    示例 1:
      输入: 1
      输出: "1"
    
    示例 2:
      输入: 4
      输出: "1211"
    
    思路
    1. 题目的逻辑就是要将前一个数“读”出来,然后变化成另一个数。可以实现一个函数,从前一个数推演出另一个数,客户需要第几个,就从头开始“读”就好了。
    2. 推进的过程就是一个遍历的过程,每次遍历到一个新数时,向后计算其数量,然后将“数量”和“数字”加入到新的字符串中。再将当前的Index移到下一个待“读”的数字。
    class Solution_38_01 {
     public:
      string countAndSay(int n) {
        if (n < 1) return "";
        string ret = "1";
        for (int i = 1; i < n; ++i) {
          ret = NextSS(ret);
        }
        return ret;
      }
      string NextSS(string str) {
        string ret;
        int index = 0;
        while (index < str.length()) {
          char curNum = str[index];
          int cnt = 1;
          while ((index + cnt) < str.length() && str[index + cnt] == curNum) {
            ++cnt;
          }
          index += cnt;
          ret.push_back(cnt + '0');
          ret.push_back(curNum);
        }
        return ret;
      }
    };
    
    // 九章上的一个实现
    // 利用了StringStream实现数字和字符串之间的转换,将上述循环中的while变为了for,实现起来感觉更清晰
    class Solution_38_02 {
     public:
      string int_to_string(int j) {
        stringstream in;
        in << j;
        string temp;
        in >> temp;
        return temp;
      }
      string genate(string s) {
        string now;
        int j = 0;
        // 这段实现比自己写的那个while要清晰,以后涉及找到一个起点,然后遍历。然后在跳n个字符的做法可以参考这个实现
        for (int i = 0; i < s.size(); i += j) {
          for (j = 0; j + i < s.size(); j++) {
            if (s[i] != s[i + j]) {
              break;
            }
          }
          now = now + int_to_string(j) + s[i];
        }
        return now;
      }
      string countAndSay(int n) {
        string s("1");
        while (--n) {
          s = genate(s);
        }
        return s;
      }
    };
    

    14. 最长公共前缀

    描述
    • 编写一个函数来查找字符串数组中的最长公共前缀。
    • 如果不存在最长公共前缀,返回空字符串 ""。
    示例
    示例 1:
      输入: ["flower","flow","flight"]
      输出: "fl"
    
    示例 2:
      输入: ["dog","racecar","car"]
      输出: ""
      解释: 输入不存在最长公共前缀。
    
    说明:
      所有输入只包含小写字母 a-z 。
    
    思路
    1. 题目要求的是最长公共前缀,不是子序列,简单一些。核心是从头开始依次遍历vector中对应位置的字符。
    2. 避免处理复杂的边界,可以优先求出最短的序列,然后按照该长度依次遍历vector中每个string对应位置的字符,相等则将对应字符保留,不相等则退出循环。(其实可以不用管最后的边界,因为字符串最后的'\0',肯定不会相等,具体可参考实现二)
    class Solution_14_01 {
     public:
      string longestCommonPrefix(vector<string>& strs) {
        if (strs.empty()) return "";
        string ret("");
        int mSize = strs[0].size();
        // 找到最短序列
        for (string str : strs) {
          if (str.size() < mSize) {
            mSize = str.size();
          }
        }
        for (int index = 0; index < mSize; ++index) {
          char tmp = strs[0][index];
          bool match = true;
          for (string str : strs) {
            if (str[index] != tmp) {
              match = false;
              break;
            }
          }
          if (!match) break;
          ret.push_back(strs[0][index]);
        }
        return ret;
      }
    };
    
    // 九章上的实现。核心思想相同,但更精炼。
    class Solution_14_02 {
     public:
      string longestCommonPrefix(vector<string>& strs) {
        if (strs.size() == 0) {
          return "";
        }
        string prefix = "";
        for (int i = 0; i < strs[0].length(); i++) {
          for (int j = 1; j < strs.size(); j++) {
            // 这里刚开始担心strs[j][i]有可能会越界,但实际上字符串最后一个字符是'\0',肯定不等,所以不用去特意求最短的字符串
            if (strs[j][i] != strs[0][i]) {
              return prefix;
            }
          }
          prefix += strs[0][i];
        }
        return prefix;
      }
    };
    

    相关文章

      网友评论

          本文标题:LeetCodeDay10

          本文链接:https://www.haomeiwen.com/subject/udkwkftx.html