1988coder

792. Number of Matching Subsequences

Dec 29th, 2018
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.73 KB | None | 0 0
  1. /**
  2.  * Pre Processing Time : O(words.length)
  3.  *
  4.  * Time Complexity: O(S.length() + Summation of all chars in all words)
  5.  *
  6.  * Space Complexity: O(words.length)
  7.  */
  8. class Solution {
  9.     class Word {
  10.         String word;
  11.         int index;
  12.  
  13.         Word(String w) {
  14.             word = w;
  15.             index = 0;
  16.         }
  17.     }
  18.  
  19.     public int numMatchingSubseq(String S, String[] words) {
  20.         if (S == null || words == null || S.length() == 0 || words.length == 0) {
  21.             return 0;
  22.         }
  23.  
  24.         Map<Character, List<Word>> map = new HashMap();
  25.         for (String word : words) {
  26.             if (word.length() > S.length()) {
  27.                 continue;
  28.             }
  29.             char c = word.charAt(0);
  30.             if (!map.containsKey(c)) {
  31.                 map.put(c, new ArrayList<Word>());
  32.             }
  33.             map.get(c).add(new Word(word));
  34.         }
  35.  
  36.         int result = 0;
  37.         for (char c : S.toCharArray()) {
  38.             if (!map.containsKey(c)) {
  39.                 continue;
  40.             }
  41.             List<Word> curBucket = map.get(c);
  42.             map.put(c, new ArrayList<Word>());
  43.             // Overall this for loop will run for summation of all chars in all words.
  44.             for (Word w : curBucket) {
  45.                 w.index++;
  46.                 if (w.word.length() == w.index) {
  47.                     result++;
  48.                 } else {
  49.                     char nextChar = w.word.charAt(w.index);
  50.                     if (!map.containsKey(nextChar)) {
  51.                         map.put(nextChar, new ArrayList<Word>());
  52.                     }
  53.                     map.get(nextChar).add(w);
  54.                 }
  55.             }
  56.             curBucket.clear();
  57.         }
  58.         return result;
  59.     }
  60. }
  61.  
  62. /*
  63.  * Using Solution of https://leetcode.com/problems/is-subsequence
  64.  *
  65.  * Pre Processing Time = O(S.length())
  66.  *
  67.  * Time Complexity: O(Sum of all word lengths * log S)
  68.  *
  69.  * Space Complexity: O(S)
  70.  */
  71. class Solution {
  72.     public int numMatchingSubseq(String S, String[] words) {
  73.         if (S == null || words == null || S.length() == 0 || words.length == 0) {
  74.             return 0;
  75.         }
  76.  
  77.         Map<Character, List<Integer>> map = processStr(S);
  78.         int result = 0;
  79.         for (String word : words) {
  80.             if (word.length() > S.length()) {
  81.                 continue;
  82.             }
  83.             if (isSubsequence(map, word)) {
  84.                 result++;
  85.             }
  86.         }
  87.         return result;
  88.     }
  89.  
  90.     private Map<Character, List<Integer>> processStr(String s) {
  91.         Map<Character, List<Integer>> map = new HashMap();
  92.         for (int i = 0; i < s.length(); i++) {
  93.             char c = s.charAt(i);
  94.             if (!map.containsKey(c)) {
  95.                 map.put(c, new ArrayList<Integer>());
  96.             }
  97.             map.get(c).add(i);
  98.         }
  99.         return map;
  100.     }
  101.  
  102.     private boolean isSubsequence(Map<Character, List<Integer>> map, String s) {
  103.         int prevIdx = -1;
  104.         for (char c : s.toCharArray()) {
  105.             if (!map.containsKey(c)) {
  106.                 return false;
  107.             }
  108.             int nextIdx = binarySearchInList(map.get(c), prevIdx);
  109.             if (nextIdx == -1) {
  110.                 return false;
  111.             }
  112.             prevIdx = nextIdx;
  113.         }
  114.         return true;
  115.     }
  116.  
  117.     private int binarySearchInList(List<Integer> list, int prev) {
  118.         int start = 0;
  119.         int end = list.size() - 1;
  120.         while (start < end) {
  121.             int mid = start + (end - start) / 2;
  122.             if (list.get(mid) <= prev) {
  123.                 start = mid + 1;
  124.             } else {
  125.                 end = mid;
  126.             }
  127.         }
  128.         return list.get(start) > prev ? list.get(start) : -1;
  129.     }
  130. }
Add Comment
Please, Sign In to add comment