【LeetCode两题选手】算法类题目(8.1)

题一:字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例1:

输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").

示例2:

输入: s1= "ab" s2 = "eidboaoo"
输出: False

注意:

输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutation-in-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路一:排序+滑动窗口(defeat)

	bool checkInclusion(string s1, string s2) {
        int sz1 = s1.size();
        int sz2 = s2.size();
        string temp;
        
        for(int i= 0;i<sz2-sz1+1;i++){
            temp = s2.substr(i,sz1);
            sort(s1.begin(),s1.end());
            sort(temp.begin(),temp.end());
            
            if(temp == s1)
                return true;
        }
        
        return false;
    }

想法是挺好的,就是超时了。

思路二:字母表+滑动窗口

核心思路:只要两个字符串的字符出现频率相同,即可证明这俩字符串是同胞兄弟姐妹。
这样就可以省去了排序的时间。

思路三:字母表+滑动窗口(优化)

当俩字符串不匹配时,将前一个字符串的第一个字母移除,后面再补一个,再比对。

public class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length())
            return false;
        int[] s1map = new int[26];
        int[] s2map = new int[26];
        for (int i = 0; i < s1.length(); i++) {
            s1map[s1.charAt(i) - 'a']++;
            s2map[s2.charAt(i) - 'a']++;
        }
        int count = 0;
        for (int i = 0; i < 26; i++)
            if (s1map[i] == s2map[i])
                count++;
        for (int i = 0; i < s2.length() - s1.length(); i++) {
            int r = s2.charAt(i + s1.length()) - 'a', l = s2.charAt(i) - 'a';
            if (count == 26)
                return true;
            s2map[r]++;
            if (s2map[r] == s1map[r])
                count++;
            else if (s2map[r] == s1map[r] + 1)
                count--;
            s2map[l]--;
            if (s2map[l] == s1map[l])
                count++;
            else if (s2map[l] == s1map[l] - 1)
                count--;
        }
        return count == 26;
    }
}


> 作者:LeetCode
> 链接:https://leetcode-cn.com/problems/permutation-in-string/solution/zi-fu-chuan-de-pai-lie-by-leetcode/
> 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题二:复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。

示例:

输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:枚举+递归

vector<string> restoreIpAddresses(string s, int index)
{
    vector<string> vip;
    if (index == 3) {
        if (s.size() == 0 || s.size() > 3 || (s.size() > 1 && s[0] == '0'))
            return vip;
        int val = atoi(s.c_str());
        if (val >= 0 && val <= 255) {
            vip.push_back(s);
        }
        return vip;
    } else {
        for (int i = 1; i < 4 && i <= s.size(); i++) {
            string tmp = s.substr(0, i);
            if (i > 1 && s[0] == '0')
                continue;
            int val = atoi(tmp.c_str());
            if (val >= 0 && val <= 255) {
                vector<string> nextv = restoreIpAddresses(s.substr(i), index+1);
                for (int k = 0; k < nextv.size(); ++k) {
                    string ip(tmp);
                    ip.append(".").append(nextv[k]);
                    vip.push_back(ip);
                }
            }
        }
    }
    return vip;
}
 
vector<string> restoreIpAddresses(string s) {
    return restoreIpAddresses(s, 0);
}

猜你喜欢

转载自blog.csdn.net/qq_43762191/article/details/107684693