佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 472|回复: 12

Google面试题目

[复制链接]
发表于 26-3-2019 05:49 AM | 显示全部楼层 |阅读模式
Given a String pattern as "ABCDFGHK" write a function if input strings like XYZCDFGABHKERYT or LOPIKHFGDCBAYRT should return the starting index of the pattern and if the intput strings are XYZCDFGABBHKERYT or LOPIKHFDBAYRGCT it should return -1.

Do not use any data structures like dict or set to store all the possible combinations of the pattern string.
The interviewer said no to regular expressions too.


有谁会解答?
回复

使用道具 举报


ADVERTISEMENT

发表于 27-3-2019 01:59 AM | 显示全部楼层
本帖最后由 SotongJiang 于 27-3-2019 02:01 AM 编辑

去面试看到这题的话,肯定超时出局。当作编程练习还是能挤一挤脑汁。
按题意是coding不能用library的data structure或RE,越原始越好。

我的C/C++差不多还给老师了,唯有偷鸡用python如下,欢迎指教。
  1. def match_pattern(inStr, pattern, p_len):
  2.     summation = 0

  3.     for c in pattern:
  4.         c_cnt = inStr.count(c)
  5.         if c_cnt==1:
  6.             summation += c_cnt
  7.         else:
  8.             break

  9.     if summation==p_len:
  10.         return True

  11.     return False


  12. def find_pattern(inStr, pattern):
  13.     p_len = len(pattern)
  14.     s_len = len(inStr)

  15.     i=0
  16.     print '%s has pattern %s in it?' % (inStr, pattern)
  17.     while (i < s_len):
  18.         if pattern.count(inStr[i])>0:
  19.             if s_len-i >= p_len:
  20.                 if match_pattern(inStr[i:i+p_len], pattern, p_len):
  21.                     
  22.                     print 'Found it at index ',i
  23.                     return i
  24.                 else:
  25.                     print 'Not found '
  26.                     return -1
  27.             else:
  28.                 #pattern string not found throughout the inStr
  29.                 return -1

  30.         i += 1


  31. find_pattern('XYZCDFGABHKERYT','ABCDFGHK')
  32. find_pattern('LOPIKHFGDCBAYRT','ABCDFGHK')
  33. find_pattern('XYZCDFGABBHKERYT','ABCDFGHK')
  34. find_pattern('LOPIKHFDBAYRGCT','ABCDFGHK')
  35.   
  36.         

复制代码

评分

参与人数 1积分 +20 收起 理由
褐眼睛 + 20 谢谢分享

查看全部评分

回复

使用道具 举报

 楼主| 发表于 27-3-2019 06:03 PM | 显示全部楼层
SotongJiang 发表于 27-3-2019 01:59 AM
去面试看到这题的话,肯定超时出局。当作编程练习还是能挤一挤脑汁。
按题意是coding不能用library的data structure或RE,越原始越好。

我的C/C++差不多还给老师了,唯有偷鸡用python如下,欢迎指教。

坦白说,我对Python不熟,但是在Visual Studio试了你的Code,结果是正确的:
3
4
-1
-1
从我在leetcode.com转载过来的那里,有关匿名人士没有给出答案,有些人就建议使用Permutation of Strings 或Anagram in Strings的方式,也有人提议用Hash 及 Sliding Window的方式。不过我请教了这里一位资深程序员,他说基本上在本地IT公司你的答案是过关的,只不过真正来说Google会不会接受则不得而知了。据我所了解,你用了str.Count这个功能。

谢谢你的参与,非常高兴看到本地也有人答题。


回复

使用道具 举报

发表于 27-3-2019 08:09 PM | 显示全部楼层
褐眼睛 发表于 27-3-2019 06:03 PM
坦白说,我对Python不熟,但是在Visual Studio试了你的Code,结果是正确的:
从我在leetcode.com转载过来的那里,有关匿名人士没有给出答案,有些人就建议使用Permutation of Strings 或Anagram in Strings的方式 ...

嘿嘿,没错用了python string里的count(), 所以我说偷鸡啊。
当然另写一个count()也ok,那就完全符合“越原始越好”的题目本意。

你看那论坛的建议,都违背了题意, hash是data structure的一种(类似dict), permutation的话也会用到library(除非大神级的自己重写)。
程序员用惯了library,突然要求不能用了就很痛苦。

上回你po的图片压缩比赛,我就无能为力了。




点评

那个编程比赛用的不是图片,而是由符号文字组成的图案啊。  发表于 28-3-2019 12:56 AM
回复

使用道具 举报

发表于 27-3-2019 10:35 PM | 显示全部楼层
我的方法不过string要ABC-Z 而已
public class Test {

        public static void main(String[] args) {

                System.out.println(checkPattern("XYZCDFGABHKERYT", "ABCDFGHK"));
                System.out.println(checkPattern("LOPIKHFGDCBAYRT", "ABCDFGHK"));
                System.out.println(checkPattern("XYZCDFGABBHKERYT", "ABCDFGHK"));
                System.out.println(checkPattern("LOPIKHFDBAYRGCT", "ABCDFGHK"));
        }

        public static int checkPattern(String input, String pattern) {

                int len = pattern.length();
                int[] patternLocation = new int[26];

                for (int i = 0; i < 26; i++) {
                        patternLocation = 0;
                }

                for (int i = 0; i < len; i++) {
                        char ch = pattern.charAt(i);
                        patternLocation[ch - 'A'] = 1;
                }
                int count = 0;
                int index = -1;
                for (int i = 0; i < input.length(); i++) {
                        char ch = input.charAt(i);
                        if (patternLocation[ch - 'A'] == 1) {
                                patternLocation[ch - 'A']= 0;
                                count=count+1;
                                index = i;
                        } else {
                                count = 0;
                                index = -1;
                        }
                        if (count == len) {
                                return index+1-len;
                        }

                }

                return -1;

        }

}


评分

参与人数 1积分 +20 收起 理由
褐眼睛 + 20 谢谢分享

查看全部评分

回复

使用道具 举报

 楼主| 发表于 28-3-2019 12:53 AM | 显示全部楼层

我用C#(改了一下,如charAt 改成ElementAt),你的答案是正确的。
我发现你的方法很新颖,是Toggle Bit的方式来完成,不过有一个缺点,虽然和题目无关:无法使用相同字母作为String Pattern喔。

十分感谢你花时间来解决这道题!
回复

使用道具 举报

Follow Us
发表于 28-3-2019 02:46 AM | 显示全部楼层
本帖最后由 martinng 于 28-3-2019 05:24 AM 编辑
  1. C#:

  2.     static void Main(string[] args)
  3.     {
  4.         string pattern = "ABCDFGHK";
  5.         string inputString = "XYZCDFGABHKERYT";
  6.         Console.WriteLine("Pattern = {0}", pattern);
  7.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //3
  8.         inputString = "LOPIKHFGDCBAYRT";
  9.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //4
  10.         inputString = "XYZCDFGABBHKERYT";
  11.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //-1
  12.         inputString = "LOPIKHFDBAYRGCT";
  13.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //-1
  14.         Console.WriteLine();

  15.         pattern = "ABBBBACDXZMARTIN";
  16.         inputString = "XYZCDFGABDZMARBBINTBAXCHKERYT";
  17.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //7
  18.         inputString = "XYZCDFGABDZMARBBINTBAABXCHKERYT";
  19.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //9
  20.         inputString = "XYZCDFGABDZMARBHBINTBAABXCHKERYT";
  21.         Console.WriteLine("Input string = {0}, index = {1}", inputString, findPattern(inputString, pattern));  //-1

  22.         Console.ReadKey();
  23.     }

  24.     static int findPattern(string inputString, string pattern)
  25.     {
  26.         int index = -1;
  27.         int patternLength = pattern.Length;
  28.         int inputStringLength = inputString.Length;
  29.         long patternValue = 0;
  30.         long inputStringValue = 0;
  31.         int bFirst = 1;
  32.         if (inputStringLength < patternLength) return index;
  33.         for (int i = 0; i < inputStringLength; i++)
  34.         {
  35.             inputStringValue = 0;
  36.             for (int j = i; j < (i + patternLength); j ++)
  37.             {
  38.                 if (bFirst == 1) patternValue += (long)1 << ((byte)(pattern[j - i]) - 65);
  39.                 inputStringValue += (long)1 << ((byte)(inputString[j]) - 65);
  40.             }
  41.             bFirst = 0;
  42.             if (patternValue == inputStringValue)
  43.             {
  44.                 index = i;
  45.                 break;
  46.             }

  47.             if ((i + patternLength) >= inputStringLength) break;               
  48.         }

  49.         return index;
  50.     }
复制代码

第五给example,其实pattern 已经改变了,变成"ABBBBACDXZMARTIN"了。
PS: 这个写得不够优化,不是O(N) running time,因为每次都重复计算inputStringValue。变成O(N^2)了。下面是更优化的版本。
screenshot.png
回复

使用道具 举报

发表于 28-3-2019 05:27 AM | 显示全部楼层
本帖最后由 martinng 于 28-3-2019 11:38 AM 编辑
  1.         static int findPattern(string inputString, string pattern)
  2.         {
  3.             int index = -1;
  4.             int patternLength = pattern.Length;
  5.             int inputStringLength = inputString.Length;
  6.             long patternValue = 0;
  7.             long inputStringValue = 0;
  8.             long firstCharValue = 0;
  9.             int bFirst = 1;
  10.             if (inputStringLength < patternLength) return index;
  11.             for (int i = 0; i < inputStringLength; i++)
  12.             {
  13.                 if (bFirst == 1)
  14.                 {
  15.                     for (int j = i; j < (i + patternLength); j++)
  16.                     {
  17.                         patternValue += (long)1 << ((byte)(pattern[j - i]) - 65);
  18.                         inputStringValue += (long)1 << ((byte)(inputString[j]) - 65);
  19.                         if (i == j) firstCharValue = (long)1 << ((byte)(inputString[j]) - 65);
  20.                     }
  21.                     bFirst = 0;
  22.                 }
  23.                 else
  24.                 {
  25. //Sliding window algorithm, 每次前进一个字母,都是减去上次的第一个字母和加上这个新字母。
  26.                     inputStringValue = inputStringValue - firstCharValue + ((long)1 << ((byte)(inputString[i + patternLength - 1]) - 65));
  27.                     firstCharValue = (long)1 << ((byte)(inputString[i]) - 65);
  28.                 }

  29.                 if (patternValue == inputStringValue)
  30.                 {
  31.                     index = i;
  32.                     break;
  33.                 }

  34.                 if ((i + patternLength) >= inputStringLength) break;               
  35.             }

  36.             return index;
  37.         }
复制代码


这个才是真正O(N) running time,就是只要loop inputstring 字母数目,就能找到答案。
P/S:程式写得很不精简,有时间再refactor吧。
回复

使用道具 举报


ADVERTISEMENT

发表于 28-3-2019 05:58 AM | 显示全部楼层
SotongJiang 发表于 27-3-2019 08:09 PM
嘿嘿,没错用了python string里的count(), 所以我说偷鸡啊。
当然另写一个count()也ok,那就完全符合“越原始越好”的题目本意。

你看那论坛的建议,都违背了题意, hash是data structure的一种(类似dict), per ...

你误解了hash的真正定义了。dict 内部可能是用hash,但hash不一定就是dict,所以hash 不是一个data structure,而是algorithm。
其实leetcode 有个鬼佬(就是那个说用sliding window + hash)已经把正确解答方式说出来了。他的所谓Hash,是为Pattern取Hash值。只是他没有讲出来到底如何取Hash值,这个才是这个题目的重点。第二个重点就是:在比较pattern hash和 input string时,必须是最多loop N次,N就是input string的长度。如果call instr,substring,indexOf等等built in function,可能会在内部执行更多次数的loop,所以不鼓励用。
回复

使用道具 举报

发表于 29-3-2019 01:09 AM | 显示全部楼层
  1.         static int findPattern(string inputString, string pattern)
  2.         {
  3.             if (inputString.Length < pattern.Length) return -1;
  4.             long patternValue = 0, inputStringValue = 0;
  5.             bool bPatternHashed = false;
  6.             for (int i = 0; (i + pattern.Length) <= inputString.Length; i++)
  7.             {
  8.                 if (!bPatternHashed)
  9.                 {
  10.                     for (int j = i; j < (i + pattern.Length); j++)
  11.                     {
  12.                         patternValue += (long)1 << ((byte)(pattern[j]) - 65);
  13.                         inputStringValue += (long)1 << ((byte)(inputString[j]) - 65);
  14.                     }
  15.                     bPatternHashed = true;
  16.                 }
  17.                 else inputStringValue -= ((long)1 << ((byte)(inputString[i - 1]) - 65)) - ((long)1 << ((byte)(inputString[i + pattern.Length - 1]) - 65));
  18.                 if (patternValue == inputStringValue) return i;
  19.             }
  20.             return -1;
  21.         }
复制代码


刚刚refactor了。
回复

使用道具 举报

发表于 30-3-2019 02:29 PM | 显示全部楼层
本帖最后由 martinng 于 30-3-2019 02:33 PM 编辑

我们全都理解错这个问题啦。其实这个问题是考对Rabin Karp rolling hash 的理解和应用能力。这个问题的正确要求:
1)pattern 的字元顺序必须一致。ABC不等于CBA。
2)是要所有occurrence,并不是first occurrence而已。 ABC,“AZX【ABC】XXTML【ABC】D”
关于2),有一个疑惑:就是如果pattern是“AA”,string 是 “AAAA”,所有occurrence到底是 0,1,2(有重叠)还是0和2而已(不重叠)

回复

使用道具 举报

发表于 31-3-2019 11:56 AM | 显示全部楼层
褐眼睛 发表于 28-3-2019 12:53 AM
我用C#(改了一下,如charAt 改成ElementAt),你的答案是正确的。
我发现你的方法很新颖,是Toggle Bit的方式来完成,不过有一个缺点,虽然和题目无关:无法使用相同字母作为String Pattern喔。

十分感谢你花 ...

改用incremental or decremental因该就可以了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 27-4-2024 04:42 AM , Processed in 0.078145 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表