Showing posts with label 尺取法. Show all posts
Showing posts with label 尺取法. Show all posts

caterpillar 尺取法 - L.J.SHOU的专栏 - 博客频道 - CSDN.NET


尺取法 - L.J.SHOU的专栏 - 博客频道 - CSDN.NET

方法的思想

The idea is to check elements in a way that's reminiscent of movements of a caterpillar.
The caterpillar crawls through the array. We remember the front and back positions of the
caterpillar, and at every step either of them is moved forward.

分析

基本思想就是让 catepillar 表示 和不大于 s 的连续子数组
Each position of the caterpillar will represent a different contiguous subsequence in which
the total of the elements is not greater than s. Let's initially set the caterpillar on the first
element. Next we will perform the following steps:
  • if we can, we move the right end (front) forward and increase the size of the caterpillar;
  • otherwise, we move the left end (back) forward and decrease the size of the caterpillar.
In this way, for every position of the left end we know the longest caterpillar that covers
elements whose total is not greater than s. If there is a subsequence whose total of elements
equals s, then there certainly is a moment when the caterpillar covers all its elements.
  1. * Caterpillar Method
  2. * (s, t) move forward
  3. * O(N) amortized time
  4. */
  5. bool existed(vector<int> &vec, int target)
  6. {
  7. if(vec.empty()) return false;
  8. int front(0), sum(0);
  9. for(int back(0); back<vec.size(); ++back) {
  10. while(front < vec.size() && sum + vec[front] <= target) {
  11. sum += vec[front];
  12. ++ front;
  13. }
  14. if(sum == target) return true;
  15. sum -= vec[back];
  16. }
  17. return false;
  18. }
  1. def caterpillarMethod(A, s):
  2. n = len(A)
  3. front, total = 0, 0
  4. for back in xrange(n):
  5. while (front < n and total + A[front] <= s):
  6. total += A[front]
  7. front += 1
  8. if total == s:
  9. return True
  10. total -= A[back]
  11. return False

Minimum window substring

Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
  1. int lengthOfLongestSubstring(string str) {
  2. if(str.size() < 2) return str.size();
  3. vector<int> hash(256);
  4. int res(0);
  5. int front(0), back(0);
  6. for(; back<str.size(); ++back) {
  7. while(front < str.size() && hash[str[front]] == 0) {
  8. ++hash[str[front]];
  9. ++ front;
  10. }
  11. res = max(res, front-back);
  12. --hash[str[back]];
  13. }
  14. return res;
  15. }

有 n 根棍子,计算能够组成的三角形的数目(棍子可以重用)。

具体地说,we have to count the number of triplets at indices x < y < z, such that Ax <= Ay <= Az, 且 Ax +Ay > Az
  1. def triangles(A):
  2. n = len(A)
  3. result = 0
  4. for x in xrange(n):
  5. z = 0
  6. for y in xrange(x + 1, n):
  7. while (z < n and A[x] + A[y] > A[z]):
  8. z += 1
  9. result += z - y - 1
  10. return result

更多题目见 codility training center

Read full article from 尺取法 - L.J.SHOU的专栏 - 博客频道 - CSDN.NET

Compute the maximum water trapped by a pair of vertical lines - EPI


Compute the maximum water trapped by a pair of vertical lines 

ContainerWithMostWater.java

  public static int getMaxArea(List<Integer> heights) {
    int i = 0, j = heights.size() - 1;
    int res = 0;
    while (i < j) {
      res = Math.max(res, Math.min(heights.get(i), heights.get(j)) * (j - i));
      if (heights.get(i) > heights.get(j)) {
        --j;
      } else if (heights.get(i) < heights.get(j)) {
        ++i;
      } else { // heights[i] == heights[j].
        ++i;
        --j;
      }
    }
    return res;
  }

Find the smallest subarray covering all values - EPI



Find the smallest subarray covering all values

SmallestSubarrayCoveringSe.java
  public static Pair<Integer, Integer> findSmallestSubarrayCoveringSubset(
      final List<String> A, final List<String> Q) {
    Set<String> dict = new HashSet<>(Q);
    Map<String, Integer> countQ = new HashMap<>();
    int l = 0, r = 0;
    Pair<Integer, Integer> res = new Pair<>(-1, -1);
    while (r < A.size()) {
      // Keeps moving r until it reaches end or countQ has |Q| items.
      while (r < A.size() && countQ.size() < Q.size()) {
        if (dict.contains(A.get(r))) {
          countQ.put(A.get(r),
              countQ.containsKey(A.get(r)) ? countQ.get(A.get(r)) + 1 : 1);
        }
        ++r;
      }

      if (countQ.size() == Q.size() && // Found |Q| keywords.
          ((res.getFirst() == -1 && res.getSecond() == -1) || r - 1 - l < res
              .getSecond() - res.getFirst())) {
        res.setFirst(l);
        res.setSecond(r - 1);
      }

      // Keeps moving l until it reaches end or countQ has less |Q| items.
      while (l < r && countQ.size() == Q.size()) {
        if (dict.contains(A.get(l))) {
          int it = countQ.get(A.get(l));
          countQ.put(A.get(l), --it);
          if (it == 0) {
            countQ.remove(A.get(l));
            if ((res.getFirst() == -1 && res.getSecond() == -1)
                || r - 1 - l < res.getSecond() - res.getFirst()) {
              res.setFirst(l);
              res.setSecond(r - 1);
            }
          }
        }
        ++l;
      }
    }
    return res;
  }


SmallestSubarrayCoveringSetStream.java

Use Double Linked list to store last occurence index of each keyword, and Hashmap to map each keyword to the corresponding node.
  public static Pair<Integer, Integer> findSmallestSubarrayCoveringSubset(
      List<String> A, List<String> Q) {

    // Tracks the last occurrence (index) of each string in Q.
    LinkedList<Integer> loc = new LinkedList<>();

    Map<String, LinkedList<Integer>.Node> dict = new HashMap<>();
    for (String s : Q) {
      dict.put(s, null);
    }

    Pair<Integer, Integer> res = new Pair<>(-1, -1);
    int idx = 0;
    String s = new String();
    for (String aA : A) {
      s = aA;
      if (dict.containsKey(s)) { // s is in Q.
        LinkedList<Integer>.Node it = dict.get(s);
        if (it != null) {
          loc.erase(it);
        }

        LinkedList<Integer>.Node back = loc.pushBack(idx);
        dict.put(s, back);
      }

      if (loc.size() == Q.size() && // Found |Q| keywords.
          ((res.getFirst() == -1 && res.getSecond() == -1) || idx
              - loc.front().item < res.getSecond() - res.getFirst())) {
        res.setFirst(loc.front().item);
        res.setSecond(idx);
      }
      ++idx;
    }
    return res;
  }

剑指Offer - 九度1516 - 调整数组顺序使奇数位于偶数前面


http://www.cnblogs.com/zhuli19901106/p/3450578.html
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。


既然要求顺序不能变,那就得保证从前往后扫描。可以用一个数组扫描两次,先后记录奇数和偶数;或者用两个数组扫描一次,记录奇数和偶数。之后再将数组写回原数组,释放额外空间即可。这种方法时间和空间复杂度均为O(n),虽然很土,但简单易懂。

我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。
void SortOddBeforeEven(int *number,int n){
    int left = 0,right = n-1;
    //下标
    int oIndex = 0,eIndex = 0;
    //二分遍历
    while(left < right){
        //从左边直到第一个偶数
        while(left < right && (number[left] % 2 != 0)){
            left++;
        }
        //从右边直到第一个奇数
        while(left < right && (number[right] % 2 == 0)){
            right--;
        }
        //奇偶数交换
        if(left < right){
            int temp;
            temp = number[left];
            number[left] = number[right];
            number[right] = temp;
        }
    }
// Use O(n) space, not good.
  1.     //O(n)--Odd number is inserted from front,Even number from tail.  
  2.     public static void sort(int[] x){  
  3.         if(x==null||x.length==0){  
  4.             return;  
  5.         }  
  6.         int len=x.length;  
  7.         int[] tmp=new int[len];  
  8.         int oddPos=0;  
  9.         int evenPos=len-1;  
  10.         for(int i=0;i<len;i++){  
  11.             if(!isEven(x[i])){  
  12.                 tmp[oddPos++]=x[i];  
  13.             }else{  
  14.                 tmp[evenPos--]=x[i];  
  15.             }  
  16.         }  
  17.         System.arraycopy(tmp, 0, x, 0, len);  
  18.     }  
 7 int main()
 8 {
 9     vector<int> b, c;
10     int n, i, tmp;
11     
12     // this solution is O(n) both in time and space.
13     while(scanf("%d", &n) == 1){
14         b.clear();
15         c.clear();
16         for(i = 0; i < n; ++i){
17             scanf("%d", &tmp);
18             tmp % 2 ? b.push_back(tmp) : c.push_back(tmp);
19         }
20         for(i = 0; i < c.size(); ++i){
21             b.push_back(c[i]);
22         }
23         c.clear();
24         printf("%d", b[0]);
25         for(i = 1; i < b.size(); ++i){
26             printf(" %d", b[i]);
27         }
28         b.clear();
29         printf("\n");
30     }
31     
32     return 0;
33 }
http://www.acmerblog.com/offer-6-2429.html
http://zhedahht.blog.163.com/blog/static/25411174200741295930898/
题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)
因此我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。
3.在函数Reorder中,用函数指针func指向的函数来判断一个数字是不是符合给定的条件,而不是用在代码直接判断(hard code)。这样的好处是把调整顺序的算法和调整的标准分开了(即解耦,decouple)。当调整的标准改变时,Reorder的代码不需要修改,只需要提供一个新的确定调整标准的函数即可,提高了代码的可维护性。例如要求把负数放在非负数的前面,我们不需要修改Reorder的代码,只需添加一个函数来判断整数是不是非负数。这样的思路在很多库中都有广泛的应用,比如在STL的很多算法函数中都有一个仿函数(functor)的参数(当然仿函数不是函数指针,但其思想是一样的)。如果在面试中能够想到这一层,无疑能给面试官留下很好的印象。

面试题精选100题(29)-调整数组顺序使奇数位于偶数前面[算法]


http://www.acmerblog.com/interview-9-2427.html
Also check http://zhedahht.blog.163.com/
题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。
要求的是把奇数放在数组的前半部分,偶数放在数组的后半部分,因此所有的奇数应该位于偶数的前面。也就是说我们在扫描这个数组的时候,如果发现有偶数出现在奇数的前面,我们可以交换他们的顺序,交换之后就符合要求了。
因此我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。
2.这道题有很多变种。这里要求是把奇数放在偶数的前面,如果把要求改成:把负数放在非负数的前面等,思路都是都一样的。
10void ReorderOddEven(int *pData, unsigned int length)
11{
12      if(pData == NULL || length == 0)
13            return;
14 
15      Reorder(pData, length, isEven);
16}
20// satisfy func in the first part, otherwise in the second part
21// Input: pData  - an array of integers
22//        length - the length of array
23//        func   - a function
24
25void Reorder(int *pData, unsigned int length, bool (*func)(int))
26{
27      if(pData == NULL || length == 0)
28            return;
29 
30      int *pBegin = pData;
31      int *pEnd = pData + length - 1;
32 
33      while(pBegin < pEnd)
34      {
35            // if *pBegin does not satisfy func, move forward
36            if(!func(*pBegin))
37            {
38                  pBegin ++;
39                  continue;
40            }
41 
42            // if *pEnd does not satisfy func, move backward
43            if(func(*pEnd))
44            {
45                  pEnd --;
46                  continue;
47            }
48 
49            // if *pBegin satisfy func while *pEnd does not,
50            // swap these integers
51            int temp = *pBegin;
52            *pBegin = *pEnd;
53            *pEnd = temp;
54      }
55}
56 
57/////////////////////////////////////////////////////////////////////////
58// Determine whether an integer is even or not
59// Input: an integer
60// otherwise return false
61/////////////////////////////////////////////////////////////////////////
62bool isEven(int n)
63{
64      return (n & 1) == 0;
65}

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts