算法刷起

目录:一、字符串

   二、数组

一、字符串(窗口滑动、字符移动)

1、把一个0-1串(只包含0和1的串)进行排序,你可以交换任意两个位置,问最少交换的次数?

//解答:快排思想,前边1与后边的0需要进行互换,计次数;O(len)复杂度;
 int answer = 0;    
 for (int i = 0, j = len – 1; i < j; ++i, --j) {
    for (;(i < j) && (a[i] == ‘0’);++i);
    for (;(j > i) && (a[j] == ‘1’); --j);
    if (i < j) ++answer;
} 

2、(1)删除一个字符串所有的a,(2)并且复制所有的b。注:字符数组足够大

int n = 0, numb = 0;
for (int i = 0; s[i]; ++i) {
    if (s[i] != ‘a’) {
        s[n++] = s[i];
    }
    if (s[i] == ‘b’) {
        ++numb;
    }
}
s[n] = 0;    
    

int newLength = n + numb; s[newLength] = 0; for (int i = newLength - 1, j = n – 1; j >=0; --j) { s[i--] = s[j]; if (s[j] == ‘b’){ s[i--] = ‘b’; } }

3、一个字符串只包含*和数字,请把它的*号都放开头

//保持顺序解法:从后向前,所有数字全部留下,剩下的全是*;
    int j = n – 1;
    for (int i = n – 1; i >= 0; --i) 
            if (isdigit(s[i])) s[j--] = s[i];
    for (; j >= 0; --j) s[j] = ‘*’;
//不保持顺序解法:从开始判断是否是*,是*就与前边的互换,2个指针,一快一慢;会打乱数字的顺序;
    for (int i = 0, j = 0; j < n; ++j) 
        if (s[j] == ‘*’) swap(s[i++], s[j]);

4、给定两个串a和b,问b是否是a的子串的变位词。例如输入a = hello, b = lel, lle, ello都是true,但是b = elo是false。

//解答:统计b中每个字的个数,然后在a中选取b长度的区域,依次验证个数是否相等;
int nonZero = 0;
for (int i = 0; i < lenb; ++i) 
    if (++num[b[i] – ‘a’] == 1) 
        ++nonZero;
for (int i = lenb; i < lena; ++i) {
    int c = a[i – lenb] – ‘a’;
    ++num[c];
    if (num[c] == 1)
        ++nonZero;
    else if (num[c] == 0)
        --nonZero;
    c = a[i] – ‘a’;
    --num[c];
    if (num[c] == 0)
        --nonZero;
    else if (num[c] == -1) 
        ++nonZero;
    if (nonZero == 0) 
        return true;
}

5、翻转句子中全部的单词,单词内容不变。例如I’m a student.  变为student. a I’m;

//解答:直接翻转会被成 .tneduts a m’I,如果对每个单词再次翻转则变成 student. a I’m,所以,找空格;
小区域反转:while (i < j) swap(s[i++], s[j--]);

二、数组

原文地址:https://www.cnblogs.com/huasky/p/11184328.html