Algorithm learning summary (to be continued)

Binary search

  • 35
  • 34
  • 1
  • 69
  • 1658
  • 81
  • 475
  • 300
  • 1011
  • 4
// Ordinary dichotomy algorithm to find the target value
while (l < r) {
	int mid = (l + r) >> 1;
	if (nums[mid] < target) {
		l = mid + 1;
	} else if (nums[mid] > target) {
		r = mid - 1;
	} else { // nums[mid] == target
		return mid;
	}
}
return -1; // Can't find

// Find the first subscript greater than or equal to the target value
while (l < r) {
    int mid = (l + r) >> 1;
    if (nums[mid] >= target) {
    	r = mid; // r is the final result
    } else {
    	l = mid + 1;
    }
}

// Find the first subscript greater than the target value
while (l < r) {
    int mid = (l + r) >> 1;
    if (nums[mid] > target) {
    	r = mid; // r is the final result
    } else {
    	l = mid + 1;
    }
}

Joint search set

Class UnionSet {
public:
    int *fa, n;
    UnionSet(int n) : n(n) {
        fa = new int[n + 1];
        for (int i = 0; i <= n; i++) fa[i] = i;
    }
    int get(int x){
        return fa[x] = (fa[x] == x ? x : get(fa[x]);
    }
    void merge(int a, int b) {
        fa[get[a]] = get(b);
   }
};

Monotone queue

Used to solve the RMQ (Range Minimum/Maximum Query) problem -- the problem of finding the interval maximum value

  • 239. Maximum value of sliding window / Sword finger Offer 59 - I. maximum value of sliding window
  • Sword finger Offer 59 - II. Maximum value of queue
  • 862, and the shortest subarray of at least k (monotone queue / sliding window)
  • 1438. Longest continuous subarray with absolute difference not exceeding the limit (sliding window + monotone queue)
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    deque<int> q;
    vector<int> ret;
    for (int i = 0; i < nums.size(); i++) {
        while (q.size() && nums[q.back()] < nums[i]) {
            q.pop_back();
        }
        q.push_back(i);
        if (i - q.front() == k) {
            q.pop_front();
        }
        if (i + 1 < k) {
            continue;
        }
        ret.push_back(nums[q.front()]);
    }
    return ret;
}

Monotone stack

Find the next larger / smaller element

  • 496. Next larger element I
  • 503. Next larger element II
  • 739. Daily temperature / Sword finger Offer II 038. Daily temperature
  • 901. Stock price span
vector<int> nextGreatElement(vector<int> & num1, vector<int> & nums2)
{
    vector<int> ret(nums.size());
    stack<int> s;
    for (int i = 0; i < nums.size(); i++) {
        while(s.size() && nums[s.top()] < nums[i]]) {
           ret[s.top()] = nums[i];
           s.pop();
        }
        s.push(i);
    }
    return ret;
}

Dictionary tree (Tire)

sliding window

  • 76. Minimum covering substring / Sword finger Offer II 017. The shortest string containing all characters
  • Sword finger Offer II 014. Modifier in string / 567. Sorting of string
  • 438. Find all letter ectopic words / Sword finger Offer II 015 in the string and all modified words in the string
  • Sword finger Offer 48, longest substring without repeated characters / 3, longest substring without repeated characters / Sword finger Offer II 016, longest substring without repeated characters
  • Super short string
void slidingWindow(string s, string t)
{
    unordered_map<char, int> h, window;
    for (char c : t) {
        h[c]++;
    }
    int l = 0;
    int r = 0;
    int valid = 0;
    while (right < s.size()) {
        char c = s[r];
        r++;
        ... // Perform a series of updates to the data in the window
        
        while (window needs shrink) {
            char d == s[l++];
            l++;
            ... // Perform a series of updates to the data in the window
        }
    }
}

Greedy and interval problem (interval greedy)

  • 435
  • 452

Difference

  • 1094. Carpooling
  • 1107. Flight reservation system

The corresponding concept of difference array is prefix and array. For array [1,2,2,4], its difference group is [1,1,0,2]. The i-th number of difference array is the difference between the i-1 st element and the i-th element of the original array, that is, we can get the original array by summing the prefix of the difference group.

The nature of the difference array is that when we want to apply an increment inc to an interval [l,r] of the original array, the corresponding change of the difference group d is: d[l] increases inc and d[r+1] decreases inc. In this way, the modification of the interval becomes the modification of two positions. And this modification can be superimposed, that is, when we apply different increments to different intervals of the original array many times, we just need to modify the difference array according to the rules.

Unfinished to be continued

Tags: C++ Algorithm

Posted on Thu, 04 Nov 2021 07:38:35 -0400 by x2fusion