LeetCode Online Judge 题目C# 练习 - Implement strStr()

Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

needle in the haystack 大海捞针的意思

其实就是找出 “短字符串” 在 “长字符串” 中的位置。

 1 public static string strStr(string haystack, string needle)

 2         {

 3             if (haystack.Length == 0)

 4                 return string.Empty;

 5             if (needle.Length == 0)

 6                 return string.Empty;

 7             if (needle.Length > haystack.Length)

 8                 return string.Empty;

 9 

10             for (int i = 0; i < haystack.Length; i++)

11             {

12                 bool found = true;

13                 for (int j = 0; j < needle.Length; j++)

14                 {

15                     if (haystack[i + j] != needle[j])

16                     {

17                         found = false;

18                         break;

19                     }

20                 }

21                 if(found)

22                     return haystack.Substring(i);

23             }

24 

25             return string.Empty;

26         }

代码分析:

  第一时间想到的应该是这个两重循环的方法,O(n2)。

 1 public static string strStrOpt(string haystack, string needle)

 2         {

 3             if (haystack.Length == 0)

 4                 return string.Empty;

 5             if (needle.Length == 0)

 6                 return string.Empty;

 7             if (needle.Length > haystack.Length)

 8                 return string.Empty;

 9 

10             //Create a partial match table

11             int[] table = new int[needle.Length];

12             partial_table(needle, table);

13 

14             // Search

15             int h_index = 0;

16             int n_index = 0;

17 

18             while (h_index + n_index < haystack.Length)

19             {

20                 if (needle[n_index] == haystack[h_index + n_index])

21                 {

22                     if (n_index == needle.Length - 1)

23                         return haystack.Substring(h_index);

24                     else

25                         ++n_index;

26                 }

27                 else

28                 {

29                     h_index = h_index + n_index - table[n_index];

30                     if (table[n_index] > -1)

31                         n_index = table[n_index];

32                     else

33                         n_index = 0;

34                 }

35             }

36 

37             return string.Empty;

38         }

39 

40         public static void partial_table(string word, int[] table)

41         {

42             if (0 == table.Length)

43                 return;

44 

45             if (1 == table.Length)

46             {

47                 table[0] = -1;

48                 return;

49             }

50 

51             table[0] = -1;

52             table[1] = 0;

53 

54             int pos = 2;

55             int cnd = 0;

56 

57             while (pos < table.Length)

58             {

59                 if (word[pos - 1] == word[cnd])

60                     table[pos++] = ++cnd;

61                 else if (cnd > 0)

62                     cnd = table[cnd];

63                 else

64                     table[pos++] = 0;

65             }

66         }

代码分析:

  为了提高效率,我们希望直接跳到needle长度后一个字符来比较。比如说。

  “ABDABDABC”中找“ABC"。如果对比完第一个"ABD"发现不相等,我们希望跳到下一个"A"开始,而不是从字符串中第二个字符"B"开始。

  但是如果needle字符串中带有重复的。比如 "ABABACAB" 中找 “ABAC" 比较完 "ABAB" != "ABAC"以后,不能跳到第3个"A"开始比较,因为needle中有重复的,这样会错过了从第二个”A"开始的“ABAC".

  所以,以上代码使用了一个array来 看needle字符串中重复位置。

  ”ABAC" 会生成ARRAY [ -1,0,0,1], 当比较到"B" != "C", h_index = h_index + n_index - table[n_index], 从第2个“A”开始再比较。

你可能感兴趣的:(LeetCode)