LintCode 1378: Minimum String Array Coverage (同向双指针经典题)

  1. Minimum String Array Coverage

Given a string collection tag_list, an array of strings all_tags, find the smallest all_tags sub-array contains all the string in the tag_list, output the length of this sub-array. If there is no return -1.

Example
Example1

Input: tag_list = [“made”,“in”,“china”], all_tags = [“made”, “a”,“b”,“c”,“in”, “china”,“made”,“b”,“c”,“d”]
Output: 3
Explanation:
[“in”, “china”,“made”] contains all the strings in tag_list,6 - 4 + 1 = 3.
Example2

Input: tag_list = [“a”], all_tags = [“b”]
Output: -1
Explanation:
Does not exist.
Notice
1 <= |tag_list|,|all_tags| <=10000
All string length <= 50
String is not repeated in tag_list

解法1:
双指针法。p2先往右移动,直到包含所有目标字符串。
然后p1往右移动,同时调整hashmap的值。如果窗口中的目标字符串都在的话,p1会一直移到p2,直到窗口中的目标字符串不全,此时p1停下,p2继续往右移动。
代码同步更新在https://github.com/luqian2017/Algorithm

class Solution {
public:
    /**
     * @param tagList: The tag list.
     * @param allTags: All the tags.
     * @return: Return the answer
     */
    int getMinimumStringArray(vector<string> &tagList, vector<string> &allTags) {
        int m = tagList.size();
        int n = allTags.size();
        if (m > n) return -1;
        
        int p1 = 0, p2 = 0;
        map<string, int> mp;
        for (int i = 0; i < m; ++i) mp[tagList[i]] = 0;
        int matchWordCount = 0;
        int minLen = INT_MAX;

        //move p2
        while(p2 < n) {
            if (mp.find(allTags[p2]) != mp.end()) {
                mp[allTags[p2]]++;
                if (mp[allTags[p2]] == 1) matchWordCount++;
                if (matchWordCount == m) {
                    minLen = min(minLen, p2 - p1 + 1);   
                    //move p1 to right
                    while(p1 < p2) {
                        if (mp.find(allTags[p1]) != mp.end()) {
                             mp[allTags[p1]]--;
                             if (mp[allTags[p1]] == 0) {
                                 matchWordCount--;
                                 p1++;
                                 break;
                             }
                        }
                        p1++;
                        minLen = min(minLen, p2 - p1 + 1);
                    }
                } 
            }
            p2++;
        }
      
        return minLen == INT_MAX ? -1 : minLen;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值