#P1555. 第1题-小美删字符
-
1000ms
Tried: 289
Accepted: 47
Difficulty: 4
所属公司 :
美团
时间 :2023年9月9日
-
算法标签>栈
第1题-小美删字符
思路:思维
相邻字符连续删除的场景,这是一个典型的栈的应用。
所以用栈这么操作后,在栈中的元素必然是 101010... 或者 010101... 这样的
这部分元素我们考虑修改,现在令栈中的元素构成的串为 t 。
t 的长度为偶数,则修改 2t 个即可。
t 的长度为奇数,则必然是 1010...101 ,那么 '0' 的个数比 '1' 的个数少 1 。至多修改 ⌊2t⌋ 即可。
考虑需要修改的次数为 cnt ,实际修改的次数为 k
k≤cnt ,则可以通过合适的修改后,可以再删除 2k 个 。
k>cnt ,则修改 cnt 个后,可以再删除 2cnt 个。
那么我们还需要修改 k−cnt 次 。
-
如果这个 k−cnt 是偶数,那么怎么修改都可以
-
如果这个 k−cnt 是奇数,那么相当于还需要修改 1 次 。
如果原串长度是奇数,那么再怎么删除都会剩下至少一个字符,所以把这 k−cnt 修改那个剩下的字符即可。
如果原串长度是偶数,那么也只需要修改一个字符,此时必然是剩下两个字符。
时间复杂度:O(n)
代码
Python
n, k = map(int, input().split())
s = input()
stk = []
for i in s:
x = int(i)
if len(stk) == 0 or stk[-1] != x:
stk.append(x)
else:
stk.pop()
res = len(stk)
cnt = len(stk) // 2
if cnt >= k:
res -= k * 2
elif cnt < k:
res -= cnt * 2
# 可以全部转换一样的,但是需要考虑几种情况
# 如果剩余字符数是奇数,那么必然是一个,剩余的修改次数均给这个字符即可
if res & 1:
pass
else:
# 否则剩余字符数为0,还有 k-cnt 次需要修改
# 如果这个是奇数,那么必然不行
# 如果是偶数,那么只要对一个字符修改偶数次即可
ch = k - cnt
if ch & 1:
res += 2
print(res)
C++
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<char> st;
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++){
char c;
cin>>c;
if(!st.empty()&&st.top()==c){
st.pop();
}
else st.push(c);
}
int cnt=st.size()/2;
int ans=0;
int size=st.size();
if(k<=cnt){
ans=size-k*2;
}
else{
if(size%2){
ans=1;
}
else{
int rest=(k-cnt);
if(rest%2){
ans=2;
}
}
}
printf("%d\n",ans);
}
Java
import java.util.Scanner;
import java.util.Stack;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n, k;
n = sc.nextInt();
k = sc.nextInt();
String s = sc.next();
Stack<Character> stack = new Stack<>();
for(int i = 0; i < n; i++){
if(stack.isEmpty()){
stack.add(s.charAt(i));
continue;
}
char ch = s.charAt(i);
char ch1 = stack.lastElement();
if (ch == ch1) {
stack.pop();
} else {
stack.add(ch);
}
}
int length = stack.size();
int min = length / 2;
if (k < min){
System.out.println(length - 2 * k);
} else if (k == min){
System.out.println(length % 2);
} else {
k -= min;
if (length % 2 == 1){
System.out.println(1);
} else {
if (k % 2 == 0) {
System.out.println(0);
} else {
System.out.println(2);
}
}
}
sc.close();
}
}
题目描述
小美有一个 01 串 s,当串中相邻字符相同时,可以将这两个相邻字符删除,得到一个新的串。一直删除到串中相邻字符均不相同。
现在,小美对这个串修改了恰好 k 次,一次修改可以将 '1' 修改为 '0' ,或者将 '0' 修改为 '1' 。
现在,小美想问你,将 s 修改恰好 k 次后,再进行删除操作,最终串的长度最短为多少?
输入描述
第一行,两个正整数 n,k(1≤k≤n≤105),表示字符串 s 的长度和修改次数。
第二行,一个长度为 n 的字符串 s ,保证 s 的字符要么是 '0' ,要么是 '1'
输出描述
k 次修改后进行删除,最终串的长度最小值。
样例
输入
4 1
1010
输出
2
说明
将第二个字符修改为 '1',然后最终的串为 "10"
样例2
输入
6 3
101111
输出
0
说明
修改第一个,第三个,第四个字符为 '0' ,最终相邻字符删除,最终的串中字符均可以删除。
串成为一个空串。