Two Pointers - How to Succeed in Algorithms


Two Pointers - How to Succeed in Algorithms

How to Succeed in Algorithms Interview Series


Types of Two/Multiple Pointers

  • One array, head and tail pointers
    • maintain interval, expand head when still meets criteria, shrink tail when not
  • Slow and fast pointers
  • 一个数组, 从两边向中间移动(对撞型)
  • 一个数组, 同时向前移动(前向型)
  • 两个数组(并行型)
  • Two arrays, both from start or end
    • when element’s value/state is related with afterwards elements
      • use stack
      • or maybe traverse from end

When to use Two/Multiple Pointers

  • range related

How

Multiple arrays (merge)
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
    List<Pair<Integer, Integer>> jobs = new ArrayList<>();
    int N = profit.length, res = 0, i = 0, maxp = 0;
    for (int j = 0; j < N; ++j) jobs.add(new Pair<Integer, Integer>(difficulty[j], profit[j]));
    Collections.sort(jobs, Comparator.comparing(Pair::getKey));
    Arrays.sort(worker);
    for (int ability : worker) {
        while (i < N && ability >= jobs.get(i).getKey())
            maxp = Math.max(jobs.get(i++).getValue(), maxp);
        res += maxp;
    }
    return res;
}
Two/Multiple same direction pointers in one array(尺取法)
// start and end of the current window
int left = 0, right = 0;
// current pointer
for (int i = 0; i < S.size(); ++ i) {
    right = max(right, last[S.at(i)]); // maximum index of the current window
    // reach the end of current window
    if (i == right) {
        vResult.push_back(right - left + 1); // size of the current window
        left = i + 1; // move to start of the next window
    }
}

Slow and fast pointers

Forward and backward pointers

Sliding Window

When to use

  • window of size k
  • Shortest/longest Subarray with xxx

How

  • expand (end pointer) the window until it meets the criteria
  • reset value when it violates
  • shrink (start pointer) to make it smallest
  • maintain states when expand and shrink: put in a map/set
  • use together with queue or monotone queue

Implementation

use together with queue or monotone queue

public int shortestSubarray(int[] A, int K) {
    int N = A.length;
    long[] P = new long[N+1];
    for (int i = 0; i < N; ++i)
        P[i+1] = P[i] + (long) A[i];

    // Want smallest y-x with P[y] - P[x] >= K
    int ans = N+1; // N+1 is impossible
    Deque<Integer> monoq = new LinkedList(); //opt(y) candidates, as indices of P

    for (int y = 0; y < P.length; ++y) {
        // Want opt(y) = largest x with P[x] <= P[y] - K;
        while (!monoq.isEmpty() && P[y] <= P[monoq.getLast()])
            monoq.removeLast();
        while (!monoq.isEmpty() && P[y] >= P[monoq.getFirst()] + K)
            ans = Math.min(ans, y - monoq.removeFirst());

        monoq.addLast(y);
    }

    return ans < N+1 ? ans : -1;
}
public int lengthOfLongestSubstring(String s) {
     if (s.length()==0) return 0;
     HashMap<Character, Integer> map = new HashMap<Character, Integer>();
     int max=0;
     for (int i=0, j=0; i<s.length(); ++i){
         if (map.containsKey(s.charAt(i))){
             j = Math.max(j,map.get(s.charAt(i))+1);
         }
         map.put(s.charAt(i),i);
         max = Math.max(max,i-j+1);
     }
     return max;
 }

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)