字符串
来源:互联网 发布:岂不到乎的拼音 编辑:程序博客网 时间:2024/06/09 22:07
例1、把一个0,1字符串进行排序,可以交换任意两个位置,问交换的次数最少多少?
算法:是一个类似于partition的过程,使用两个数组指针,找到尾部指针是0且首部指针是1的情况才能交换一次。
class Solution {public: int get01swaptimes(vector<int>nums) { if(nums.size() == NULL) return 0; int res = 0; int i = 0; int j = (int)nums.size() - 1; while (i<j){ while (i<j && nums[i]!=1) i++; while (i<j && nums[j]!=0) j--; if(i<j){ res++; i++; j--; } } return res;};
例2、删除一个字符串的所有a,并且复制所有的b两次.(涉及到数组复制或其他需要增加数组内个数的问题的时候,都应先计算后新数组的长度,再从后向前复制。可以把时间复杂度从n^2降到n)
算法:
1、删除的a很简单,可以使用一个新的数组慢指针,在字符串遍历的时候,如果不等于a,就复制,等于a跳过。可以在o(n)时间删除字符
2、在遍历的同时,将b的个数统计出来count,因为新数组会复制两次b,那么新字符串会比旧字符串长2*count。并且对字符串resize
3、在复制b的时候就倒着复制整个字符串,就可以在o(N)复杂度得出新数组。
class Solution {public: void delAndCopyString(string& str,char a,char b){ if(str.size() == 0) return; //遍历统计b的个数,并删除a int countb = 0; int na = 0; for (int i = 0; i < str.size(); ++i) { if(str[i] == b) countb++; if(str[i] != a) str[na++] = str[i]; } str[na] = '\0'; //复制b int newlength = na + 2 * countb; str.resize((unsigned long) newlength); int k = newlength -1; for (int j = na-1; j >=0 ; j--) { if(str[j] == b){ //复制2次b,最后会有3个b for (int i = 0; i < 3; ++i) { str[k--] = str[j]; } } else str[k--] = str[j]; } str[newlength] = '\0'; }};
例3、子串变位词,给定2个字符串,问b是不是a的子串变位词.
变位词:长度相同,字符相同,但顺序不一定相同。
子串:必须是连续的
子序列:属于原字符串的字符就可以,不要求连续。
比如a=hello 那么ell ,lol都是子串变位词,但是hlo就不是,因为不是子串。
算法:
运用滑动窗口算法,从头开始划,然后比较划出来的子串和b是否是变位词。
leetcode 3
在字符串中找到最长的不重复的子串,求出子串的长度
class Solution {public: int getValueNumFromMap(map<char,int> mp){ map<char,int>::iterator mit; int count = 0; for ( mit = mp.begin(); mit != mp.end(); mit++) { count += mit->second; } return count; } map<char,int> window(string s,int begin ,int end){ map<char,int> res; //故意不要最后一个,为了循环方便// for (int i = begin; i <end; i++) { if(res.count(s[i])) res[s[i]] += 1; else res[s[i]] = 1; } return res; } int lengthOfLongestSubstring(string s) { if(s.size() == 0) return 0; int length = s.size(); int len = s.size() -1 ; map<char,int>::iterator it; while (len > 0) { //j代表窗口的尾巴// int k = 0; int j = len--; map<char,int> tmp = window(s,k,j); while ((k+j)<length) { int start = k++; int end = start+j; //判断哈希表里是否有新加来的数,如果有就跳过// if(tmp.count(s[end])) tmp[s[end]]+=1; else{ tmp[s[end]] = 1; int keynum = tmp.size(); int valuenum = getValueNumFromMap(tmp); if(keynum >= valuenum) return end - start + 1; } //删除第一个,继续向下滑动 it = tmp.find(s[start]); if(it->second == 1) tmp.erase(it); else tmp[s[start]] -= 1; } } return 1; }};
例4、字符串翻转,字符串移位
算法:算法相同,使用的都是部分翻转,再整体翻转。
0 0
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- keepalive的 nopreempt 非抢占
- NYOJ168房间安排
- ViewPager与侧滑冲突
- 说说MySQL中的事务
- main中的数组args传值
- 字符串
- Linux下非Root用户解决ImportError: No module named bz2
- linux 学习(一)
- 调用系统打电话和发短信
- JAVA学习
- CSS3的calc()使用
- 二维矩阵的旋转问题(二维数组作为函数参数)
- hive lateral view 与 explode详解
- 实验吧/隐写术/水果