leetcode第三题

来源:互联网 发布:淘宝客服用的打字软件 编辑:程序博客网 时间:2024/06/02 04:35

最近终于拾起了久违的编程,开始做leetcode上的题,开始看啊哈磊的《啊哈!算法》,忽然觉得算法其实是很有意思的,当然这是建立在会编程的基础之上的,所以我现在致力于学好C++和编程,也许有一天我也可以成为大神呢哈哈~不得不承认我真的是太菜,需要学习的东西还有很多,抱大牛们大腿啊。。由于数据结构知识不牢固,导致对于最简答的题目都想不到好的解决方法,可是我已经开始在不断地进步和学习了,每天学习一点,会有收获的~我要开始坚持写CSDN博客了,看到大牛们的高深莫测,让我更有动力去学习!

最近接触排序的算法,发现了一个很好用的思路,就是充分利用数组的下标来标记元素是否出现过,排序中的桶排序就是这个原理,需要注意的是,只要涉及到去重或者无重复这样的关键词,就要想到用哈希表(如leetcode第一题)或者是标记法。

leetcode上的第三题让我受益匪浅,我学习到了很多不同的解决方法。

思路一:最直接的枚举法。从所给字符串中找出所有的子串,然后判断每一个子串是否含有相同的元素即可。

class Solusion{public:    int lengthOfLongestSubstring(string s){int i = 0, j = 0, k = 0;int len = s.length();int maxlen = 0;string tempstr = "";for (i = 0; i < len; i++){for (j = i+1; j <= len; j++){//获得从i到j的子字符串,一共有n*(n+1)/2个子字符串tempstr = s.substr(i, j-i);//判断子串中是否有重复出现的元素bool exist[256] = {false};bool repeat = false;for (k = 0; k < tempstr.length(); k++){//如果字串中存在重复元素if (exist[tempstr[k]] == true){repeat = true;break;}exist[tempstr[k]] = true;}//如果当前处理的子串没有重复字符if (!repeat){if (tempstr.length() > maxlen){maxlen = tempstr.length();}}}}return maxlen;}};
这个代码在leetcode上能够正常运行,一个网友写的代码中有个错误,现已改正:
k < tempstr.length();

在提交代码的时候,出现错误Time Limit Exeeded,该算法的时间复杂度是O(n^3),算法复杂度太高。

思路二:用一个数组(256个)来标记元素是否出现,用两个指针 i,j 来表示子串的起始和终止位置,这也是leetcode官网给出的答案,算法时间复杂度是O(n)。这里值得注意的一个问题是,最后一次比较不要忘记,因为在 j 非0的时候,i - j 并不是子串的长度。

 012345678910要查找的字符串abcdcabcde  i , j 初始位置 i, j          无重复元素时 i 往前移动 j  i ->         第一次查到重复元素位置 j   i      此时 j 移动到重复元素位置   j i       i, j 同时往前移动一个位置    j  i     如此反复    j    i          j    i 注意:最后一次也是需要比较的      j     i

class Solution{public:    int lengthOfLongestSubstring(string s){        if (s.empty())return 0;int len = s.size();int bitmap[256] = {0};int maxlen = 0;int j = 0;for (int i = 0; i < len; i++){if (bitmap[s[i]] == 0){bitmap[s[i]] = 1;}else{maxlen = max(maxlen, i - j);//对bitmap进行设置,将重复元素之前的所有元素对应的位置设为0,因为这些元素不参与下一次子串while (s[i] != s[j]){bitmap[s[j]] = 0;j++;}j++;}}maxlen = max(maxlen, len - j); //注意最后还要判断一下return maxlen;}};

思路三:网友的一种巧妙的解决方案值得思考,就是首先将数组(256个)的每个元素设为-1,idx表示当前子串的起始位置的前一个位置的下标,算法复杂度也是O(n)。(反正这个解法我是想不出来。。至今还在感叹某人的聪慧。。)直接放上大神的代码和自己的一点理解吧~

class Solution{public:    int lengthOfLongestSubstring(string s)int locs[256]; //标记元素是否出现过memset(locs, -1, sizeof(locs));int idx = -1, max = 0; //idx为当前子串的起始位置的前一个位置for (int i = 0; i < s.size(); i++){//如果当前元素出现过,那么当前子串的起始位置为这个字符上一次出现的位置+1if (locs[s[i]] > idx){//新子串的起始位置设为s[i]出现的位置+1//idx为当前子串的起始位置的前一个位置的下标idx = locs[s[i]];}//如果当前子串的长度大于最大值if (i - idx > max){max = i - idx;}//更新元素s[i]出现的位置locs[s[i]] = i;}return max;};
这是我总结的一些思考方法,希望自己以后回头看现在的代码时,会有种醍醐灌顶的感觉。

谢谢~我会继续努力的~


0 0
原创粉丝点击