http://www.1point3acres.com/bbs/thread-145290-1-1.html
// Find the largest K such that A^K is a subsequence of B, where A, B are two strings. |A| << |B|.
// Power of a string:
// Let A = xyxz 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�.
// Then,
// A^1 = A = xyxz
// A^2 = xxyyxxzz
// A^3 = xxxyyyxxxzzz
. 1point 3acres 璁哄潧
// Example:-google 1point3acres
// A = xyxz
// B = xabyzxz
// B xaybyxzxxxzz
// A xxyyxxzz
一开始思路就是k从1一个个试,不行就返回。找subsequence用dp。但是面试官说复杂度太高,就想到用双指针遍历。然后问了时间复杂度。 写好后他还要improve.想到用二分查找k.因为最小是1,最大是B.length()/A.length();
subsequence是不需要连续的。如果x^(K+1)是y的subsequence,x^(K)一定是y的subsequence
// Find the largest K such that A^K is a subsequence of B, where A, B are two strings. |A| << |B|.
// Power of a string:
// Let A = xyxz 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�.
// Then,
// A^1 = A = xyxz
// A^2 = xxyyxxzz
// A^3 = xxxyyyxxxzzz
. 1point 3acres 璁哄潧
// Example:-google 1point3acres
// A = xyxz
// B = xabyzxz
// B xaybyxzxxxzz
// A xxyyxxzz
The key of the problem is to find out the largest possible k, that the A^k is the subsequence of B.
How to find out the maximum K. The easiest way is k = lenB / lenA. But that could result to a false larger K.
A better approach is to calculate the frequency of each character in A and B. Then calculate the MIN(B[i] / A[i]).
How to find out the maximum K. The easiest way is k = lenB / lenA. But that could result to a false larger K.
A better approach is to calculate the frequency of each character in A and B. Then calculate the MIN(B[i] / A[i]).
public int findK(String A, String B) { int len1 = A.length(), len2 = B.length(); if (len1 > len2) { return 0; } if (len1 <= 0) { return 0; } // remove space weird characters, capital to lower case etc if needed A = preprocess(A); // find signature for each A and B and get the max possible value for k int[] sigA = new int[256]; int[] sigB = new int[256]; for (int i = 0; i < len1; i++) { sigA[A.charAt(i)]++; } for (int i = 0; i < len2; i++) { sigB[B.charAt(i)]++; } int kMax = Integer.MAX_VALUE; for (int i = 0; i < len1; i++) { if (sigA[A.charAt(i)] != 0) { kMax = Math.min(sigB[A.charAt(i)] / sigA[A.charAt(i)], kMax); } } int lo = 0, hi = kMax; int ret = 0; while (lo <= hi) { int med = lo + (hi - lo) / 2; if (isSubSeq(expand(A, med), B)){ ret = med; lo = med + 1; } else { hi = med - 1; } } return ret; } String expand(String A, int k){ StringBuilder sbuf = new StringBuilder(); for (int i = 0; i < A.length(); i++) { char c = A.charAt(i); for (int j = 0; j < k; j++) { sbuf.append(c); } } return sbuf.toString(); } boolean isSubSeq(String A, String B) { int len1 = A.length(), len2 = B.length(); int a = 0, b = 0; while (a < len1 && b < len2){ if (A.charAt(a) == B.charAt(b)){ a++; b++; } else { b++; } } return a == len1; } String preprocess(String A){ return A.toLowerCase(); }- public int findK(String A, String B){
- int len1 = A.length(), len2 = B.length();
- if (len1 > len2) return 0;
- if (len1 <= 0) return 0;
- // remove space weird characters, capital to lower case etc if needed.
- A = preprocess(A);
- // find signature for each A and B and get the max possible value for k. 鐗涗汉浜戦泦,涓€浜╀笁鍒嗗湴
- int[] sigA = new int[256];
- int[] sigB = new int[256];. Waral 鍗氬鏈夋洿澶氭枃绔�,
- for (int i = 0; i < len1; i++) sigA[A.charAt(i)]++;
- for (int i = 0; i < len2; i++) sigB[B.charAt(i)]++;
- int kMax = Integer.MAX_VALUE;. 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴
- for (int i = 0; i < len1; i++){
- if (sigA[A.charAt(i)] != 0) kMax = Math.min(sigB[A.charAt(i)] / sigA[A.charAt(i)], kMax);
- }
- int lo = 0, hi = kMax;. 鍥磋鎴戜滑@1point 3 acres
- int ret = 0;
- while (lo <= hi){
- int med = lo + (hi - lo) / 2;
- if (isSubSeq(expand(A, med), B)){
- ret = med;
- lo = med + 1; 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�.
- } else {
- hi = med - 1;
- }
- }
- return ret;
- }
- String expand(String A, int k){
- StringBuilder sbuf = new StringBuilder();
- for (int i = 0; i < A.length(); i++){
- char c = A.charAt(i);
- for (int j = 0; j < k; j++) sbuf.append(c);
- }. more info on 1point3acres.com
- return sbuf.toString();
- }
- boolean isSubSeq(String A, String B){
- int len1 = A.length(), len2 = B.length();
- int a = 0, b = 0;
- while (a < len1 && b < len2){
- if (A.charAt(a) == B.charAt(b)){
- a++;
- b++;
- } else {
- b++;. 鐗涗汉浜戦泦,涓€浜╀笁鍒嗗湴
- }
- }
- return a == len1;. 鐗涗汉浜戦泦,涓€浜╀笁鍒嗗湴
- }
- String preprocess(String A){
- return A.toLowerCase();
- }
一开始思路就是k从1一个个试,不行就返回。找subsequence用dp。但是面试官说复杂度太高,就想到用双指针遍历。然后问了时间复杂度。 写好后他还要improve.想到用二分查找k.因为最小是1,最大是B.length()/A.length();
subsequence是不需要连续的。如果x^(K+1)是y的subsequence,x^(K)一定是y的subsequence
- public int findLargestK(String s1, String s2){.鏈枃鍘熷垱鑷�1point3acres璁哄潧
- if(s1.length() < 1 || s1.length() > s2.length())
- return -1;
- int k = 1;
- int left = 1, right = s2.length() / s1.length();
- int lastK = -1;
- while(left <= right){
- k = left + (right - left)/2;
- String akString = generateKth(s1, k);
- if(isSub(akString, s2)){
- lastK = k;
- left = k + 1;
- }else{. visit 1point3acres.com for more.
- right = k - 1;
- }
- }
- return lastK;
- }
- private String generateKth(String s, int k){
- StringBuilder temp = new StringBuilder();
- for(int i = 0; i < s.length(); i++){
- for(int j = 0; j < k; j++){. Waral 鍗氬鏈夋洿澶氭枃绔�,
- temp.append(s.charAt(i));
- }
- }
- return temp.toString();
- }. more info on 1point3acres.com
- private boolean isSub(String s1, String s2){
- int i = 0;
- int j = 0;
- while(i < s1.length() && j < s2.length()){
- if(s1.charAt(i) == s2.charAt(j)){. 1point 3acres 璁哄潧
- i++;
- }
- j++;-google 1point3acres
- }
- if(i == s1.length())
- return true;
- return false;
- }