《慕课网玩转算法面试》笔记及习题解答3.7 ~3.8

来源:互联网 发布:洪恩软件开天辟地下载 编辑:程序博客网 时间:2024/06/04 19:39

LeetCode 209

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.


滑动窗口法,两指针同向移动,注意移动时的两个指针的前后关系

int minSubArrayLen(int s, vector<int>& nums) {    if(nums.empty())return 0;    int min_len = nums.size()+1;    int i = 0 , j = 0;   // do things in [i,...,j]    int sum = nums[0];    bool found = false;    while(  i <= j && j < nums.size())    {if( sum >= s){    min_len = min( min_len, j - i + 1);    sum -= nums[i++];}    else sum += nums[++j];    }    if(min_len > nums.size())return 0;    elsereturn min_len;    }


LeetCode 3

思路:使用前后两个指针构建滑动窗口[l,...,r]每次判断r+1是否在窗口中,否则r右移,同时记录s[r+1]已经在窗口中, 是则l左移,同时记录s[l]不在窗口中。使用char dict{256}作为记录


注意:

(1)因为滑动窗口为[l,...,r],所以初始r=-1窗口为空

(2)滑动窗口中的元素保证都是不同的,那么每次都应该是判断s[r+1]的元素是否重复,需要注意判断越界。

  (3)  每次遇到重复元素,应当将左指针移动到靠前的重复元素的右边

    int lengthOfLongestSubstring(string s) {        char record[256] = {0};        //[l,....,r] is the substring        int l = 0, r = -1;        int N = s.length();        int max_len = 0;        while(r < N-1){            if( record[s[r+1]] == 0 )                record[s[++r]] = 1;            else{                while(s[l] != s[r+1]){//左指针从左向右寻找靠左的重复元素,并将遍历的元素都设为0                    record[s[l++]] = 0;                }                record[s[l++]] = 0;//找到该重复元素后将左指针再移动一次,注意此时右指针不需要移动            }            //cout << "l:" << l << "  r:" << r <<endl;            max_len = max(max_len, r-l+1);        }        return max_len;    }


练习题

LeetCode 438

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.


思路:利用 l , r 作为固定长度的滑动窗口的左右指针,每次滑动一个位置,判断是否满足条件。 可以用判断一个dict是否都为0来作为条件,初始将dict对应 p 中元素都+1, 对s中的每个元素都-1, 条件满足时dict中所有元素的值都为0.

bool isAnagrams(char dict[]){    for(char i = 'a'; i <= 'z'; i++)if(dict[i])    return false;    return true;}vector<int> findAnagrams(string s, string p) {    int n_s = s.length(); //numbers(length) of s    int n_p = p.length(); //numbers(length) of p    vector<int> res;   //res for result    if(n_s < n_p)return res;    char dict[256] = {0};        for(int i = 0; i < n_p; i++)    {dict[p[i]]++;dict[s[i]]--;    }    int l = 0, r = n_p -1;//[l,...,r] is the sliding window    while(r < n_s)    {if(isAnagrams(dict))    res.push_back(l);if(r+1 < n_s){    dict[s[++r]]--;    dict[s[l++]]++;}else    break;             }    return res;   }



76

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".


思路:使用滑动窗口,每次根据表判断是否满足条件,当满足条件,l向右移动找出最小, 如果不满足条件,则r向右移动扩大范围, 注意此时判断条件 dict[i]可以为负数

bool covered( int dict[]) // judge if s[left,..,right] covers all elems of string t{    for(int i = 0; i < 256; i++)if(dict[i] > 0)    //注意,这里dict[i]可以 < 0,如s = "bba", t ="ba",此时dict['b'] = -1也是满足的{  //cout << "i:" << i << " dict[i]" << dict[i] << endl;  return false;}        return true;}string minWindow(string s, string t) {    int s_len = s.length();    int t_len = t.length();    int dict[256] = {0};    int t_dict[256] = {0};    for(int i = 0; i < t_len; i++)    {dict[t[i]]++;t_dict[t[i]]++;    }    int l = 0, r = -1;  // [l,..,r] for sliding window    int min_left = -1,  min_right = -1;   // the left and right index of the min window [min_left,...,min_right]    int min_len = s_len + 1;   // mininum length of the window substring    while( l < s_len )    {if( covered(dict))  //判断是否为满足条件的子字符串{    //cout << "covered" << endl;    if(r - l + 1 <  min_len)    {min_len = r - l + 1;min_left = l;min_right = r;                      }    if( t_dict[s[l]] )  //当s[l]属于t时,才对dict中的s[l] ++dict[s[l]]++;    l++;}else{    if(r + 1 < s_len){if( t_dict[s[r+1]]) //当s[r+1]属于t时,才对dict中的s[r+1] ++    dict[s[r+1]]--;r++;    }    elsebreak;}//cout << "l:" << l<< " r:" << r <<  " min_left:" << min_left << " min_right:" << min_right << endl;    }    return s.substr(min_left,min_len);}





阅读全文
0 0
原创粉丝点击