最少 1s 提供力量,使整个阵列强大
给定一个二进制数组和一个整数 k,其中每个 1 都有权力,它可以将权力借给邻居和它自己。值为 1 的像元可以在距离 < k的范围内提供电力。任务是找到最小数量的 1 需要提供能量,以便所有细胞都变得强大。
如果无法使整个数组变得强大,则返回 -1。
例子:
Input : arr[] = {0, 1, 1, 1, 1, 0}
K = 2
Output : 2
arr[1] and arr[5] need to lend
Input : arr[] = {1, 0, 1, 0, 0, 1, 0, 0, 0, 1}
K = 3
Output : 3
a[2], a[5] and a[9] lend to their right side zeros.
Input : arr[] = {1, 1, 1}
K = 2
Output : 1
arr[1] need to lend power to all cells.
一个简单的解决方案是尝试所有可能的 1 组合,从一个 1 开始,然后是两个 1,依此类推,直到我们找到一个组合使整个数组变得强大。
一个有效的解决方案是基于观察到每个单元的距离 k 内应该有一个 1。我们对数组进行预处理并创建一个辅助数组,该数组存储左侧最接近 1 的索引。我们遍历整个数组并找到当前单元k距离内最近的左边1的索引。如果没有左 1,我们返回 -1。否则,我们增加 ans 并在 k 距离后移动到下一个单元格。
C++
// C++ program to minimum of number of lendings
// by 1s.
#include
using namespace std;
int minLendings(int arr[], int n, int k)
{
// Create an auxiliary array and fill
// indexes of closest 1s on left side.
int leftOne[n];
int oneInd = -1;
for (int i = 0; i < n; i++) {
if (arr[i] == 1)
oneInd = i;
leftOne[i] = oneInd;
}
// Traverse the array from left side. If
// current element has a 1 on
int ans = 0;
for (int i = 0; i < n;) {
// Find index of closest 1 after shift of
// k-1 or end whichever is closer.
int pos = leftOne[min(i + k - 1, n - 1)];
// If there is no closest 1 within allowed
// range.
if (pos == -1 || pos + k <= i)
return -1;
// If a closest 1 is found, check after k
// jumps and increment answer.
i = pos + k;
ans++;
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 0, 1, 1, 1, 1, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 2;
cout << minLendings(arr, n, k);
return 0;
}
Java
// Java program to minimum of number of
// lendings by 1s.
import java.math.*;
class GFG {
static int minLendings(int arr[], int n, int k)
{
// Create an auxiliary array and fill
// indexes of closest 1s on left side.
int leftOne[] = new int[n];
int oneInd = -1;
for (int i = 0; i < n; i++) {
if (arr[i] == 1)
oneInd = i;
leftOne[i] = oneInd;
}
// Traverse the array from left side. If
// current element has a 1 on
int ans = 0;
for (int i = 0; i < n;) {
// Find index of closest 1 after shift of
// k-1 or end whichever is closer.
int pos = leftOne[Math.min(i + k - 1, n - 1)];
// If there is no closest 1 within
// allowed range.
if (pos == -1 || pos + k <= i)
return -1;
// If a closest 1 is found, check after k
// jumps and increment answer.
i = pos + k;
ans++;
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 0, 1, 1, 1, 1, 0 };
int n = arr.length;
int k = 2;
System.out.println(minLendings(arr, n, k));
}
}
// This code is contributed by Prerna Saini
Python3
# Python3 program to minimum
# of number of lendings by 1s.
def minLendings(arr, n, k):
# Create an auxiliary array and fill
# indexes of closest 1s on left side.
leftOne = [0 for i in range(n + 1)]
oneInd = -1
for i in range(n):
if (arr[i] == 1):
oneInd = i
leftOne[i] = oneInd
# Traverse the array from left side.
# If current element has a 1 on
ans = 0; i = 0
while(i < n):
# Find index of closest 1 after shift of
# k-1 or end whichever is closer.
pos = leftOne[min(i + k - 1, n - 1)]
# If there is no closest 1
# within allowed range.
if (pos == -1 or pos + k <= i):
return -1
# If a closest 1 is found, check after k
# jumps and increment answer.
i = pos + k
ans += 1
return ans
# Driver program
arr = [ 0, 1, 1, 1, 1, 0 ]
n = len(arr)
k = 2
print(minLendings(arr, n, k))
# This code is contributed by Anant Agarwal.
C#
// C# program to minimum of number of
// lendings by 1s.
using System;
class GFG {
static int minLendings(int []arr, int n, int k)
{
// Create an auxiliary array and fill
// indexes of closest 1s on left side.
int []leftOne = new int[n];
int oneInd = -1;
for (int i = 0; i < n; i++)
{
if (arr[i] == 1)
oneInd = i;
leftOne[i] = oneInd;
}
// Traverse the array from left side.
// If current element has a 1 on
int ans = 0;
for (int i = 0; i < n;)
{
// Find index of closest 1 after
// shift of k-1 or end whichever
// is closer.
int pos = leftOne[Math.Min(i + k - 1,
n - 1)];
// If there is no closest 1 within
// allowed range.
if (pos == -1 || pos + k <= i)
return -1;
// If a closest 1 is found, check
// after k jumps and increment answer.
i = pos + k;
ans++;
}
return ans;
}
// Driver code
public static void Main()
{
int []arr = { 0, 1, 1, 1, 1, 0 };
int n = arr.Length;
int k = 2;
Console.WriteLine(minLendings(arr, n, k));
}
}
// This code is contributed by vt_m.
PHP
Javascript
输出 :
2