算法刷起
目录:一、字符串
二、数组
一、字符串(窗口滑动、字符移动)
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--]);
二、数组