由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - google scramble string O(n) 解法
相关主题
做了一下scramble stringgoogle 面试题
LeetCode Scramble String 疑问大公司算法题
关于leetcode的Scramble String问题[discussion] how to approve that the given 9*9 is a sudoku
facebook的面试题求bitmap相关资料的推荐
问一道算法题顶风上来问道题:一个很大char[], 如何in-place 删除重复元素
amazon问题求教How to solve this Interview question... thanks
问一道Career Cup里面的题如何检查是否连续
MS intern 电面被拒,附上面试过程请教个题
相关话题的讨论汇总
话题: int话题: scramble话题: s1话题: bool话题: return
进入JobHunting版参与讨论
1 (共1页)
s*******f
发帖数: 1114
1
1. get index of s1 in s2, for each char in s1, mark position is s2.
here "tiger" in "itreg" is [1, 0, 4, 3, 2]
stops和posts is: 2 3 1 0 4
//For duplication, always pick nearer one first. I use "set" to deal with
duplication in code.
At first I use brute force here with O(n square). But when using
hash_map >, it goes to O(n), or queue hm[256]
.no need to use "set" for duplication.
2. rule for eat: you can eat neighbour if your high or low bound
can "touch" neighbour.
here [1, 0, 4, 3, 2] -> 1 eat 0 [0, 1], 4 eat 3 [3, 4], then eat 2 [2, 4],
than eat [0, 1] --> [0, 4]
3. if you can eat into 1 snake, return true;
//This is bottom up solution. Look the following tree itself for ideas.
//since no standard proof provided, welcome to use your test case to beat
this:)
//zzzz码遍本版,回报本版zzzz
//scramble string
//7. scramble string,对一个string,比如tiger,可以随便找一个partition tree
// tiger
// / \
// ti ger
/// \ / \
//t i g er
// / \
// e r
//你可以选择在每个非叶子节点翻转或者不翻转两个儿子的顺序,比如可以变成
// itreg
// / \
// it reg
/// \ / \
//t i g re
// / \
// e r
//那么就称itreg是可以通过tiger串scramble得到的
//给s1, s2,求是否能找到s1一颗partition tree和翻转方案,使得得到s2
//other than 3D dynamic P. I got some new idea
//
bool DoIntArray(int a[], int len){
if (len < 4)
return true;
stack > sk;
for (int i = 0; i < len; ++i){
pair pa = make_pair(a[i], a[i]);
while (!sk.empty()){
if (pa.first - sk.top().second == 1){ //eat left
side
pa.first = sk.top().first;
sk.pop();
} else if (sk.top().first - pa.second == 1){
pa.second = sk.top().second;
sk.pop();
} else {
break;
}
}
sk.push(pa);
}
if (sk.size() == 1)
return true;
else
return false;
}
bool Scramble(const string &s1, const string &s2){
if (s1.size() != s2.size())
return false;
int *index = new int[s1.size()];
int k = 0;
queue mp[256];
for (int j = 0; j < s2.size(); ++j){
mp[s2[j]].push(j);
}
for (int i = 0; i < s1.size(); ++i){
if (mp[s1[i]].empty())
return false;
index[k++] = mp[s1[i]].front();
mp[s1[i]].pop();
}
/* set visited;
for (int i = 0; i < s1.size(); ++i){
int j = 0;
for (; j < s2.size(); ++j){
if (visited.find(j) != visited.end())
continue;
if (s1[i] == s2[j]){
visited.insert(j);
break;
}
}
if (j == s2.size()) return false;
}
*/ bool b = DoIntArray(index, s1.size());
delete[] index;
return b;
}
void TestScramble(){
bool a = Scramble("tiger", "itreg");
bool b = Scramble("abcd", "bdac");
bool c = Scramble("tigerr", "itrerg");
bool d = Scramble("tigerr", "irertg");
}
c****p
发帖数: 6474
2
stops和posts中的两个s怎么标号?

【在 s*******f 的大作中提到】
: 1. get index of s1 in s2, for each char in s1, mark position is s2.
: here "tiger" in "itreg" is [1, 0, 4, 3, 2]
: stops和posts is: 2 3 1 0 4
: //For duplication, always pick nearer one first. I use "set" to deal with
: duplication in code.
: At first I use brute force here with O(n square). But when using
: hash_map >, it goes to O(n), or queue hm[256]
: .no need to use "set" for duplication.
: 2. rule for eat: you can eat neighbour if your high or low bound
: can "touch" neighbour.

s*******f
发帖数: 1114
3
nice point.
stops和posts is: 2 3 1 0 4
For duplication, always pick nearer one first. I use "set" to deal with
duplication.

【在 c****p 的大作中提到】
: stops和posts中的两个s怎么标号?
j********e
发帖数: 1192
4
我的想法是先找root分割位置。满足下面条件的就行:
1)该位置把原s1和s2分成了4个字串,这4个字串包含的字符集应该两两相同。


【在 s*******f 的大作中提到】
: 1. get index of s1 in s2, for each char in s1, mark position is s2.
: here "tiger" in "itreg" is [1, 0, 4, 3, 2]
: stops和posts is: 2 3 1 0 4
: //For duplication, always pick nearer one first. I use "set" to deal with
: duplication in code.
: At first I use brute force here with O(n square). But when using
: hash_map >, it goes to O(n), or queue hm[256]
: .no need to use "set" for duplication.
: 2. rule for eat: you can eat neighbour if your high or low bound
: can "touch" neighbour.

w****x
发帖数: 2483
5
贴一个递归和DP的:
/*
scramble string,judge if one string can be scrambled to another one
tiger
/ \
ti ger
/ \ / \
t i g er
/ \
e r
rotation is allowded
itreg
/ \
it reg
/ \ / \
t i g re
/ \
e r
then tiger can be changed to itreg
*/
bool _inner_can_scramble(const char* szStr1, const char* szStr2, int n);
bool CanScramble(const char* szStr1, const char* szStr2)
{
assert(szStr1 && szStr2);
int nLen1 = strlen(szStr1);
int nLen2 = strlen(szStr2);
if (nLen1 != nLen2)
return false;
return _inner_can_scramble(szStr1, szStr2, nLen1);
}
bool _inner_can_scramble(const char szStr1[], const char szStr2[], int n)
{
assert(szStr1 && szStr2);
if (0 >= n || (n == 1 && szStr1[0] == szStr2[0]))
return true;
for (int i = 1; i < n; i++)
{
if ( _inner_can_scramble(szStr1, szStr2, i) &&
_inner_can_scramble(szStr1+i, szStr2+i, n-i))
return true;
if (_inner_can_scramble(szStr1, szStr2+n-i, i) &&
_inner_can_scramble(szStr1+i, szStr2, n-i))
return true;
}
return false;
}
//Obviously, previous recursion solution contains duplicated
//calculation, use DP to save the duplicated results
bool CanScrambleDP(const char* szStr1, const char* szStr2)
{
int nLen1 = strlen(szStr1);
int nLen2 = strlen(szStr2);
if (nLen1 != nLen2)
return false;
//allocate
//pRec[i][j][k] means can szStr1(i ... i+k)
//be scrambled to szStr2(j ... j+k)
bool*** pRec = new bool**[nLen1];
for (int i = 0; i < nLen1; i++)
{
pRec[i] = new bool*[nLen1];
for (int j = 0; j < nLen1; j++)
{
pRec[i][j] = new bool[nLen1];
for (int k = 0; k < nLen1; k++)
pRec[i][j][k] = false;
}
}
for (int i = 0; i < nLen1; i++)
{
for (int j = 0; j < nLen1; j++)
pRec[i][j][0] = (szStr1[i] == szStr2[j]);
}
for (int l = 1; l < nLen1; l++)
{
for (int i = 0; i+l < nLen1; i++)
{
for (int j = 0; j+l < nLen1; j++)
{
bool bRes = false;
for (int k = i+1; k <= i+l; k++)
{
if ((pRec[i][j][k-i-1] && pRec[k][k][i+l-k])
|| (pRec[i][j+l+1-k+i][k-i-1] && pRec[k][j][i+l-k]))
{
pRec[i][j][l] = true;
break;
}
}
}
}
}
bool bRet = pRec[0][0][nLen1-1];
for (int i = 0; i < nLen1; i++)
{
for (int j = 0; j < nLen1; j++)
delete []pRec[i][j];
delete []pRec[i];
}
delete []pRec;
return bRet;
}
b****e
发帖数: 45
6
字符集相同并不一定保证scramble可行,比如以下两个字符串:
"abcde"
"dbeac"
似乎没有办法通过scramble得到。

【在 j********e 的大作中提到】
: 我的想法是先找root分割位置。满足下面条件的就行:
: 1)该位置把原s1和s2分成了4个字串,这4个字串包含的字符集应该两两相同。
:

S****h
发帖数: 115
7
赞lz的想法!!
不过我在leetcode上测试了下,small test, 下面连个测试案例没通过。不知道是我少
考虑什么地方么?感觉主要问题就是‘always pick nearer one first',当然可以通
过permutation来fix.
"abab", "bbaa" false true

"bbaa", "abab" false true


【在 s*******f 的大作中提到】
: 1. get index of s1 in s2, for each char in s1, mark position is s2.
: here "tiger" in "itreg" is [1, 0, 4, 3, 2]
: stops和posts is: 2 3 1 0 4
: //For duplication, always pick nearer one first. I use "set" to deal with
: duplication in code.
: At first I use brute force here with O(n square). But when using
: hash_map >, it goes to O(n), or queue hm[256]
: .no need to use "set" for duplication.
: 2. rule for eat: you can eat neighbour if your high or low bound
: can "touch" neighbour.

s*******f
发帖数: 1114
8
nice. Let me double check. ‘always pick nearer one first' just try to
avoid twisted, but need proof. so now maybe wrong.
watch muvie first

【在 S****h 的大作中提到】
: 赞lz的想法!!
: 不过我在leetcode上测试了下,small test, 下面连个测试案例没通过。不知道是我少
: 考虑什么地方么?感觉主要问题就是‘always pick nearer one first',当然可以通
: 过permutation来fix.
: "abab", "bbaa" false true
:
: "bbaa", "abab" false true
:

j********e
发帖数: 1192
9
我没有说字符集相同就能scramble,字符集相同是必要条件,而不充分。
我的做法是,先找到一个位置i在s1,j在s2使得分割后的4个字符串两两
有相同的字符集(i=j 或者i=N-j)。然后接着对这2对字符串继续做同样
的事情连寻找分割位置。这样递归下去,如果有某对字符串无法找到分割
位置,则表示失败。否则,最后分隔最小的字符串只有一个字符。就可以
判断scramble成功。
问题是,如果有多个分割位置,是否任选一个都可以?如果必须测试每个可能的分割位置,那复杂度就不好说了。
下面是我的简单实现代码,通过了leetcode的online judge (包括judge large)。这段代码中会处理所有可能的分割位置。如果只选第一个可能的分割位置,有一个测试失败了。
#include
#include
#include
#include
using namespace std;
#define BITMAP_LEN 256
bool compare_char_set(const char *s1, const char *s2, int len) {
int bitmap[BITMAP_LEN];
int i;
//char t1[len+1], t2[len+1];
//strncpy(t1, s1, len);
//strncpy(t2, s2, len);
//t1[len] = t2[len] = 0;
//printf("Compare t1: %s, t2: %s, n is %d\n", t1, t2, len);
memset(bitmap, 0, sizeof(int)*BITMAP_LEN);
for(i=0; i bitmap[(unsigned int)s1[i]] ++;
bitmap[(unsigned int)s2[i]] --;
}
for(i=0; i if(bitmap[i]!=0)
return false;
return true;
}
bool test_scramble(const char *s1, const char *s2, int n) {
if(!s1 || !s2)
return false;
if(n == 1)
if(*s1 == *s2)
return true;
else
return false;
//char t1[n+1], t2[n+1];
//strncpy(t1, s1, n);
//strncpy(t2, s2, n);
//t1[n] = t2[n] = 0;
//printf("Test t1: %s, t2: %s, n is %d\n", t1, t2, n);
// Find root place
for(int i=1; i bool find_root = false;
if(compare_char_set(s1, s2, i) && compare_char_set(s1+i, s2+i, n-i)) {
find_root = true;
//printf("Find first type root position %d\n", i);
if(test_scramble(s1, s2, i) && test_scramble(s1+i, s2+i, n-i))
return true;
}
if(compare_char_set(s1, s2+(n-i), i) && compare_char_set(s1+i, s2, n-i)) {
find_root = true;
//printf("Find second type root position %d\n", i);
if(test_scramble(s1, s2+(n-i), i) && test_scramble(s1+i, s2, n-i))
return true;
}
//if(find_root)
// break;
}
return false;
}
class Solution {
public:
bool isScramble(string s1, string s2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(s1.length() != s2.length())
return false;

return test_scramble(s1.c_str(), s2.c_str(), s1.length());
}
};

【在 b****e 的大作中提到】
: 字符集相同并不一定保证scramble可行,比如以下两个字符串:
: "abcde"
: "dbeac"
: 似乎没有办法通过scramble得到。

B*******1
发帖数: 2454
10
My code
pass all the test on 1337 online judge.
bool isScrambleHelper(const string &s1, const string &s2, map string>, bool> &myMap)
{
pair key = make_pair(s1, s2);
if (myMap.count(key) != 0) return myMap[key];
bool result = false;
if (s1 == s2) {
result = true;
} else if (s1.size() != s2.size() ) {
result = false;
} else {
for (int i = 1; i < s1.size(); i++) {
if ((isScrambleHelper(s1.substr(0, i), s2.substr(0,i),myMap) &&
isScrambleHelper(s1.substr(i, s1.size()-i), s2.substr(i, s2.
size()-i), myMap)) ||
(isScrambleHelper(s1.substr(0, i), s2.substr(s2.size()-i,i),
myMap) &&
isScrambleHelper(s1.substr(i, s1.size()-i), s2.substr(0,s1.
size()-i), myMap))) {
result = true;
break;
}
}
}
myMap[key] = result;
return result;
}
class Solution {
public:
bool isScramble(string s1, string s2) {
map, bool> myMap;
return isScrambleHelper(s1, s2, myMap);
}
};
相关主题
amazon问题求教google 面试题
问一道Career Cup里面的题大公司算法题
MS intern 电面被拒,附上面试过程[discussion] how to approve that the given 9*9 is a sudoku
进入JobHunting版参与讨论
j********e
发帖数: 1192
11
你的代码太暴力,Judge Large需要2s左右,有时候还会超时。
我前面贴的代码大概需要20多ms。

,

【在 B*******1 的大作中提到】
: My code
: pass all the test on 1337 online judge.
: bool isScrambleHelper(const string &s1, const string &s2, map: string>, bool> &myMap)
: {
: pair key = make_pair(s1, s2);
: if (myMap.count(key) != 0) return myMap[key];
: bool result = false;
: if (s1 == s2) {
: result = true;

t*****j
发帖数: 1105
12
我也回报一下。递归的,复杂度是二叉树层数*字符串个数。空间复杂度也是O(n).
今晚刚写的,test过了。
bool isSubAnargm(string parent, string child)
{
if(parent.empty() && child.empty()) return true;
for(unsigned int i = 0; i< child.size(); i++)
{
if (parent.find(child[i]) < 0) return false;
}
if (parent.find(child[0]) > parent.find(child[child.size()-1]))
{
reverse(parent.begin(), parent.end());
};
if (parent.compare(child) == 0) return true;
int currentMaxPosition = -1;
int validMaxLength = -1;
for(unsigned int i = 0; i< child.size()-1; i++)
{
if (currentMaxPosition < (signed int)(parent.find(child[i])))
{
currentMaxPosition = parent.find(child[i]);
}
if (currentMaxPosition == i)
{
validMaxLength = currentMaxPosition;
}
}
if(validMaxLength == -1)
{
return false;
};

return isSubAnargm(parent.substr(0,validMaxLength+1),
child.substr(0,
validMaxLength+1)) && isSubAnargm(parent.substr(validMaxLength+1,
parent.
size()-validMaxLength-1), child.substr(validMaxLength+1, parent.size()-
validMaxLength-1));
}

with

【在 s*******f 的大作中提到】
: 1. get index of s1 in s2, for each char in s1, mark position is s2.
: here "tiger" in "itreg" is [1, 0, 4, 3, 2]
: stops和posts is: 2 3 1 0 4
: //For duplication, always pick nearer one first. I use "set" to deal with
: duplication in code.
: At first I use brute force here with O(n square). But when using
: hash_map >, it goes to O(n), or queue hm[256]
: .no need to use "set" for duplication.
: 2. rule for eat: you can eat neighbour if your high or low bound
: can "touch" neighbour.

c********p
发帖数: 1969
13
mark
x*****0
发帖数: 452
14
mark
m********c
发帖数: 105
15
贴一个我的recursive代码,time complexity是O(n^2),large Judge用了144ms,不
是最优解,但是容易理解
bool isScramble(string s1, string s2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function

if (s1 == s2)
return true;

int size = s1.size();

int value1=0, value2=0;
for (int i=0; i value1 += (s1[i]-'a');
value2 += (s2[i]-'a');
}
if (value1 != value2)
return false;

for (int i=1; i if (isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.
substr(i), s2.substr(i)))
return true;
if (isScramble(s1.substr(0,i), s2.substr(size-i)) && isScramble(
s1.substr(i), s2.substr(0,size-i)))
return true;
}
return false;
}
s*******n
发帖数: 305
16
都是牛人, mark
1 (共1页)
进入JobHunting版参与讨论
相关主题
请教个题问一道算法题
去掉单向链表中的重复元素 with O(n) time and O(1) (转载)amazon问题求教
leetcode-- scramble string问一道Career Cup里面的题
有人面试碰到过scramble string这个题吗?MS intern 电面被拒,附上面试过程
做了一下scramble stringgoogle 面试题
LeetCode Scramble String 疑问大公司算法题
关于leetcode的Scramble String问题[discussion] how to approve that the given 9*9 is a sudoku
facebook的面试题求bitmap相关资料的推荐
相关话题的讨论汇总
话题: int话题: scramble话题: s1话题: bool话题: return