题目难度:二星
考察点:字符串、模拟
方法:模拟
1.分析:
这个题的题意有点弯弯绕,我们来重新解读一下题意,给定一个只包含'C'和'D'的字符串s,问经过最少多少次移动之后,才能使得所有的'C'在一起,所有的'D'在一起,即将整个字符串s分为左右两部分,要么所有的'C'在字符串左边,要么所有的'D'在左边。其实我们根据这个解读之后的题意就可以进行模拟了,假设我们要求的是将所有的'C'移动到左边,那么我们就可以遍历字符串s,定义两个变量ans=0,sum=0,分别表示移动次数和字符'C'的个数,那么我们每遇到一个‘C’,就需要计算ans和sum,怎么计算呢?其实很简单,sum当然等于sum+1,而ans也是挺好计算的:ans=ans += (i-sum); 因为下标i前面有sum个'C',而这些是不需要移动的,所以直接加i-sum就可以了。同理我们在计算所有的'D'移动到左边需要多少步,那么结果就是两者取最小值。
举个例子:假设字符串s="CCDCCC",需要将'C'全部移动到左边。
当i=0时,此时s[i]=='C',那么显然ans+=(i-sum)=(0-0)=0,即不需要移动,sum = 1
当i=1时,此时s[i]=='C',那么显然ans+=(i-sum)=(1-1)=0,即不需要移动,sum = 2
当i=2时,此时s[i]=='D',那么显然不进行移动,即ans=0和sum =2不变
当i=3时,此时s[i]=='C',那么显然ans+=(i-sum)=0+(3-2)=1,即总共需要移动一下,sum = 3
当i=4时,此时s[i]=='C',那么显然ans+=(i-sum)=1+(4-3)=2,即总共需要移动两下,sum = 4
当i=5时,此时s[i]=='C',那么显然ans+=(i-sum)=2+(5-4)=3,即总共需要移动三下,sum = 5
所以对于字符串s来说,将所有的'C'移动到左边需要移动3步。
(1). 输入字符串s;
(2). 定义一个函数get_ans(char), 表示按照上述算法求将ch全部移动到左边需要的移动次数;
(3). 输出min(get_ans('C'), get_ans('D'));
2.复杂度分析:
时间复杂度:O(n)空间复杂度:O(1)
3.代码:
#include <bits/stdc++.h> using namespace std; string s; int get_ans(char ch) { int len = s.size(), ans = 0, sum = 0; for(int i=0; i<len; i++) { if(s[i] == ch) { ans += (i-sum); sum++; } } return ans; } int main() { cin>>s; cout<<min(get_ans('C'),get_ans('D'))<<endl; return 0; }