给定长度为N且整数K的二进制字符串str ,任务是找到分配的权重的最大可能和,该权重可以通过翻转给定二进制字符串中的最多K个位来获得。分配给该字符串字符的权重如下:
- 如果字符为“ 0” ,则权重为0 。
- 如果一个字符为‘1’并且其前面的字符也是‘1’ ,则权重为2 。
- 如果一个字符为‘1’并且在其之前没有字符或该字符之前的字符为‘0’ ,则权重为1 。
例子:
Input: str = “10100”, K = 2
Output: 7
Explanation:
1st flip: Flip the character at index 1, the string becomes “11100”.
2nd flip: Flip the character at index 3, the string becomes “11110”.
The weight of the resulting string is 1 + 2 + 2 + 2 + 0 = 7, which is maximum.
Input: str = “100101”, K = 1
Output: 6
Explanation:
1st flip: Flip the character at index 5, the string becomes “100111”.
The weight of the resulting string is 1 + 0 + 0 + 1 + 2 + 2 = 6, which is maximum.
做法:字符“1”的“1”之后出现的重量是所有字符中最伟大的,所以最大限度的总和,尽量创造尽可能多这样的1秒。可以将要翻转为1的0的段划分优先级,如下所示:
- 第一优先级:翻转两个1之间封闭的所有0 ,这将使形式10…01的段的权重增加(2 *(封闭的0的数量)+ 1)。如果x大于或等于封闭的0数,否则为2 *(封闭的0数)。
- 第二优先度”以1秒的第一次出现之前的字符串中的字符串的开头翻转为0,这将增加形式0的链段的重…由2 *(翻转数的0的)01。
- 第三优先级:在字符串的最后一次出现1之后,在字符串末尾翻转0 ,这将使形式10…0的段的权重增加2 *(翻转的0的数量)。
按照上述优先级翻转给定字符串的字符,以使权重最大化,然后在最多翻转K次之后找到所得字符串的权重。
以下是此方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to find maximum sum of
// weights of binary string after
// at most K flips
int findMax(string s, int n, int k)
{
int ans = 0;
// Stores lengths of substrings
// of the form 1..00..1s
int l = 0;
// Stores the index of last 1
// encountered in the string
int ind = -1;
// Stores the index of first 1
// encountered
int indf = -1;
// Stores lengths of all substrings
// having of 0s enclosed by 1s
// at both ends
multiset ls;
// Traverse the string
for (int i = 0; i < n; i++) {
// If character is 0
if (s[i] == '0')
l++;
// If character is 1
// First Priority
else if (s[i] == '1'
&& l > 0 && ans != 0) {
ls.insert(l);
l = 0;
}
// Second Priority
if (s[i] == '1') {
ind = i;
l = 0;
if (indf == -1)
indf = i;
// Add according to the
// first priority
if (i > 0 && s[i - 1] == '1')
ans += 2;
else
ans += 1;
}
}
// Stores length of the shortest
// substring of 0s
int curr;
// Convert shortest substrings
// of 0s to 1s
while (k > 0 && !ls.empty()) {
curr = *ls.begin();
// Add according to the
// first priority
if (k >= curr) {
ans += (2 * curr + 1);
k -= curr;
}
// Add according to the
// third priority
else {
ans += (2 * k);
k = 0;
}
ls.erase(ls.begin());
}
// If more 0s can be made into 1,
// then check for 0s at ends
if (k > 0) {
// Update the ans
ans += (2 * min(k,
n - (ind + 1))
- 1);
k -= min(k, n - (ind + 1));
if (ind > -1)
ans++;
}
// If K is non-zero, then flip 0s
// at the beginning
if (k > 0) {
ans += (min(indf, k) * 2 - 1);
if (indf > -1)
ans++;
}
// Return the final weights
return ans;
}
// Driver Code
int main()
{
// Given string str
string str = "1110000101";
int N = str.length();
// Given K flips
int K = 3;
// Function Call
cout << findMax(str, N, K);
return 0;
}
Python3
# Python 3 program of the above approach
# Function to find maximum sum of
# weights of binary string after
# at most K flips
def findMax( s, n, k):
ans = 0;
# Stores lengths of substrings
# of the form 1..00..1s
l = 0;
# Stores the index of last 1
# encountered in the string
ind = -1;
# Stores the index of first 1
# encountered
indf = -1;
# Stores lengths of all substrings
# having of 0s enclosed by 1s
# at both ends
ls = set([])
# Traverse the string
for i in range(n):
# If character is 0
if (s[i] == '0'):
l+=1
# If character is 1
# First Priority
elif (s[i] == '1'
and l > 0 and ans != 0):
ls.add(l);
l = 0;
# Second Priority
if (s[i] == '1') :
ind = i;
l = 0;
if (indf == -1):
indf = i;
# Add according to the
# first priority
if (i > 0 and s[i - 1] == '1'):
ans += 2;
else:
ans += 1;
# Stores length of the shortest
# substring of 0s
curr = 0
# Convert shortest substrings
# of 0s to 1s
while (k > 0 and len(ls)!=0):
for i in ls:
curr = i
break
# Add according to the
# first priority
if (k >= curr):
ans += (2 * curr + 1);
k -= curr;
# Add according to the
# third priority
else :
ans += (2 * k);
k = 0;
ls.remove(curr);
# If more 0s can be made into 1,
# then check for 0s at ends
if (k > 0) :
# Update the ans
ans += (2 * min(k,
n - (ind + 1))
- 1);
k -= min(k, n - (ind + 1));
if (ind > -1):
ans+=1
# If K is non-zero, then flip 0s
# at the beginning
if (k > 0):
ans += (min(indf, k) * 2 - 1);
if (indf > -1):
ans+=1
# Return the final weights
return ans
# Driver Code
if __name__ == "__main__":
# Given string str
s = "1110000101";
N = len(s)
# Given K flips
K = 3;
# Function Call
print(findMax(s, N, K));
# This code is contributed by chitranayal
14
时间复杂度: O(N)
辅助空间: O(N)