字符串

来源:互联网 发布:岂不到乎的拼音 编辑:程序博客网 时间: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
原创粉丝点击