根据给定条件从给定二进制字符串中删除所有 1 的最低成本
给定一个1和0的二进制序列。我们的任务是通过以下操作以最小成本从序列中删除所有 1。
- 从左端移除一个 1(即移除 s[0]),它花费 1 个硬币。
- 从右端移除一个 1(即移除 s[s.length – 1]),它花费 1 个硬币。
- 从序列中花费 2 个硬币的任意位置删除一个 1。
返回从序列中删除所有 1 的最小成本。
例子:
Input: s = “1100101”
Output: 5
Explanation:
Remove left most “1100101″ in cost of 1 coin, new s = “100101”
Remove left most “100101″ in cost of 1 coin, new s = “00101”
Remove right most “00101” in cost of 1 coin, new s = “0010”
Remove middle 1 (“0010″) in cost of 2 coin, new s = “000”.
So total 5 coins are required
Input: s = “0010”
Output: 2
Explanation: Remove middle 1 (“0010”) in cost of 2 coin, new s = “000”
方法:这个想法是使用带有滑动窗口的DP。使用数组 dp[N] ,其中 dp[i] 存储最小硬币以从索引 i 到 n-1 删除所有 1,我们只能从右侧删除。请按照以下步骤操作。
- 从最右边的索引循环。因此,对于任何索引 i,转换如下:
- 如果是“0”,则 dp[i]=dp[i+1]
- 如果它是“1”,那么我们有两个选择——要么将此元素视为中间元素,然后将 2 添加到 dp[i+1] 或删除所有元素。因此,dp[i]=min(dp[i+1]+2, ni)
- 现在,还要从左侧删除元素。所以,遍历向量。
- 当我们到达任何索引 i 时,我们将认为我们已经从左侧删除了从 0 到 i 的所有元素。
- 因此,我们对该索引的时间将是 i+1+dp[i+1]。
- 因为,我们已经删除了直到 i 的所有元素,我们只需要考虑 i+1 中的元素,因此我们将 dp[i+1] 添加到我们的 i+1。
- 最后返回最小答案
下面是代码实现:
C++
// C++ program for find the minimum cost
// to remove all 1's from the given binary string
#include
using namespace std;
// Function to find minimum cost
int minimumCoin(string s)
{
int n = s.length();
vector dp(n, 0);
if (s[n - 1] == '0') {
dp[n - 1] = 0;
}
else {
dp[n - 1] = 1;
}
for (int i = n - 2; i >= 0; i--) {
if (s[i] == '0')
dp[i] = dp[i + 1];
if (s[i] == '1') {
// consider current index to
// be a middle one and remove
dp[i] = 2 + dp[i + 1];
// or remove all to the right
dp[i] = min(dp[i], n - i);
}
}
// now go from left to right
int ans = dp[0];
for (int i = 0; i < n - 1; i++) {
// cost of removing all
// from left and dp[i+1]
ans = min(ans, i + 1 + dp[i + 1]);
}
// taking overall minimum
ans = min(ans, n);
return ans;
}
// Driver function
int main()
{
string str = "1001001";
int coins = minimumCoin(str);
cout << coins;
return 0;
}
Java
//Java program for find the minimum cost
// to remove all 1's from the given binary string
import java.io.*;
class GFG {
// Function to find minimum cost
static int minimumCoin(String s)
{
int n = s.length();
int dp[] = new int[n];
if (s.charAt(n - 1) == '0') {
dp[n - 1] = 0;
}
else {
dp[n - 1] = 1;
}
for (int i = n - 2; i >= 0; i--) {
if (s.charAt(i) == '0')
dp[i] = dp[i + 1];
if (s.charAt(i) == '1') {
// consider current index to
// be a middle one and remove
dp[i] = 2 + dp[i + 1];
// or remove all to the right
dp[i] = Math.min(dp[i], n - i);
}
}
// now go from left to right
int ans = dp[0];
for (int i = 0; i < n - 1; i++) {
// cost of removing all
// from left and dp[i+1]
ans = Math.min(ans, i + 1 + dp[i + 1]);
}
// taking overall minimum
ans = Math.min(ans, n);
return ans;
}
// Driver function
public static void main (String[] args) {
String str = "1001001";
int coins = minimumCoin(str);
System.out.println(coins);
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python code for the above approach
# Function to find minimum cost
def minimumCoin(s):
n = len(s)
dp = [0]*n
if (s[n - 1] == '0'):
dp[n - 1] = 0
else:
dp[n - 1] = 1
for i in range(n-2, -1, -1):
if s[i] == '0':
dp[i] = dp[i + 1]
if s[i] == '1':
# consider current index to
# be a middle one and remove
dp[i] = 2 + dp[i + 1]
# or remove all to the right
dp[i] = min(dp[i], n - i)
# now go from left to right
ans = dp[0]
for i in range(0, n-1):
# cost of removing all
# from left and dp[i+1]
ans = min(ans, i + 1 + dp[i + 1])
# taking overall minimum
ans = min(ans, n)
return ans
# Driver function
str = "1001001"
coins = minimumCoin(str)
print(coins)
# This code is contributed by Potta Lokesh
C#
// C# program for find the minimum cost
// to remove all 1's from the given binary string
using System;
class GFG {
// Function to find minimum cost
static int minimumCoin(string s)
{
int n = s.Length;
int[] dp = new int[n];
if (s[n - 1] == '0') {
dp[n - 1] = 0;
}
else {
dp[n - 1] = 1;
}
for (int i = n - 2; i >= 0; i--) {
if (s[i] == '0')
dp[i] = dp[i + 1];
if (s[i] == '1') {
// consider current index to
// be a middle one and remove
dp[i] = 2 + dp[i + 1];
// or remove all to the right
dp[i] = Math.Min(dp[i], n - i);
}
}
// now go from left to right
int ans = dp[0];
for (int i = 0; i < n - 1; i++) {
// cost of removing all
// from left and dp[i+1]
ans = Math.Min(ans, i + 1 + dp[i + 1]);
}
// taking overall minimum
ans = Math.Min(ans, n);
return ans;
}
// Driver function
public static void Main()
{
string str = "1001001";
int coins = minimumCoin(str);
Console.Write(coins);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
4
时间复杂度: O(n)
空间复杂度:O(n)