DP (8) -- Is Subsequence,Ugly Number II

7 篇文章 0 订阅

Is Subsequence

Given a string s and a string t, check if s is subsequence of t.

You may assume that there is only lower case English letters in both s and tt is potentially a very long (length ~= 500,000) string, and s is a short string (<=100).

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while "aec" is not).

Example 1:
s = "abc"t = "ahbgdc"

Return true.

1. 直接逐个查找。

    bool isSubsequence(string s, string t) {
        int index = 0;
        for(int i = 0; i < t.size(); i++){
           if(s[index] == t[i]) index++;
        }
        if(index == s.size()) return true;
        return false;
    }


Follow up:
If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?


1. 记录t中每个char的index

2. 如果s[i-1]的在t中的最小位置大于s[i]的所有位置,说明不是subsequence

    bool isSubsequence(string s, string t) {
        //build a record the index of each char in t
        vector<vector<int>> record(26);
        //add indexs
        for(int i = 0; i < t.size(); i++) {
            record[t[i]-'a'].push_back(i);
        }
        //check if each char in s is in the legal place
        int index = -1;
        for(int i = 0; i < s.size(); i++) {
            auto iter = upper_bound(record[s[i]-'a'].begin(), record[s[i]-'a'].end(), index);  //大于s[i-1]位置的最小位置
            if(iter == record[s[i]-'a'].end()) return false;
            index = *iter;  //s[i]的当前位置
        }
        return true;
    }


Ugly Number II

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number, and n does not exceed 1690.

1. 从最开始想,k[1] = min (k[0] * 2, k[0] * 3, k[0] *5),k[2] = min (k[1] * 2, k[0] * 3, k[0] *5)...  DP单纯的去想状态怎么描述很难,尝试去找他们的递推关系式,找规律。

2. k[i]记录第i个ugly number,每新生成一个ugly number,该number都能再生成3个ugly number,但要确保每次生成的是最小的ugly number.

3. 可以假设有3个list,每个list储存的是 *2,*3,*5 生成的ugly number,注意3个list中会有重复值,比如2 * 5 和 5 * 2。p2, p3, p5是3个list的指针,比如p3代表下一个由 * 3 生成的ugly number是 k[p3] * 3生成的。这里使用3个pointer标记*2,*3,*5各自用来产生ugly number最小的ugly number index。

4. 每次选下一个*2, *3, *5 生成的ugly number 中最小的作为第i个 ugly number。k[i] = min(k[p2]*2, min(k[p3]*3, k[p5]*5));

    int nthUglyNumber(int n) {
        vector<int> k(n);
        int p2 = 0, p3 = 0, p5 = 0;
        k[0] = 1;
        for(int i = 1; i < n; i++){
            k[i] = min(k[p2]*2, min(k[p3]*3, k[p5]*5));
            if(k[i] == k[p2] * 2) p2++;  //确定k[i]是谁生成的,并跳过重复的值,k[i]可能有多个生成方式
            if(k[i] == k[p3] * 3) p3++;
            if(k[i] == k[p5] * 5) p5++;
        }
        return k[n-1];
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值