通过将数组元素替换为数组的总和,将数组修改为另一个给定数组第 2 组
给定一个数组 input[]最初仅由1 s 和一个大小为N的数组target[]组成,任务是通过将input[i]替换为数组元素的总和来检查数组input[]是否可以转换为target[]每一步。
例子:
Input: input[] = { 1, 1, 1 }, target[] = { 9, 3, 5 }
Output: YES
Explanation:
Replacing input[1] with (input[0] + input[1] + input[2]) modifies input[] to { 1, 3, 1 }
Replacing input[2] with (input[0] + input[1] + input[2]) modifies input[] to { 1, 3, 5 }
Replacing input[0] with (input[0] + input[1] + input[2]) modifies input[] to { 9, 3, 5 }
Since the array input[] equal to the target[] array, the required output is “YES”.
Input: input[] = { 1, 1, 1, 1 }, target[] = { 1, 1, 1, 2 }
Output: NO
朴素方法:本文的Set-1中已经提到了朴素方法和贪婪方法。
有效方法:有效解决问题的想法基于以下直觉:
- Instead of trying to check if target[] array can be reached, work backward and try to generate the array of 1s from the target[].
- While working backward the maximum element of the array will be the sum of elements after the last turn. To keep track of the maximum element, use a max heap.
- After every turn, remove the maximum element from the heap and determine the previous maximum element value. To do this find the sum of all elements of the array.
请按照以下步骤解决问题:
- 创建变量sum和lastSum以存储所有元素的总和以及上一步数组的总和。
- 要确定前一个元素,求“sum”和“lastSum”与“lastSum”的差,即(lastSum - (sum - lastSum))。
- 然后将此值放回堆并更新sum 。
- 继续此操作,直到总和等于 1 或lastSum等于 1。
- 如果lastSum小于sum或sum等于 0 或lastSum 与 sum 之差为零,则返回 false。
以下是上述方法的实现:
C++
// C++ code for the above approach:
#include
using namespace std;
// Function to find if target[] can be reached
bool createTarget(vector& target)
{
// Initialise size of target array
int n = target.size();
// Initialise variable to store
// sum of values
int sum = 0;
// Initialise variable to store
// last sum
int lastSum;
// Initialise a max-heap to keep track
// of the maximum element
priority_queue maxHeap(target.begin(),
target.end());
// Start traversing to find the sum
for (int i = 0; i < n; i++) {
sum = sum + target[i];
}
// While heap has element traverse
while (true) {
// Update last sum with
// maximum value of heap
lastSum = maxHeap.top();
// Pop the maximum element
// of the heap
maxHeap.pop();
// Update sum of values
sum = sum - lastSum;
// If either sum or last sum is
// equal to 1, then
// target array possible
if (lastSum == 1 || sum == 1) {
// Return true
return true;
}
// If last sum becomes less than
// sum or if sum becomes equal
// to 0 or if difference of last
// sum and sum becomes 0
if (lastSum < sum || sum == 0
|| lastSum - sum == 0) {
// Return false
return false;
}
// Update last sum
lastSum = lastSum - sum;
// Update sum
sum = sum + lastSum;
// Push last sum into the queue
maxHeap.push(lastSum);
}
}
// Driver code
int main()
{
int N = 2;
vector target = { 2, 3 };
bool ans = createTarget(target);
if (ans)
cout << "YES";
else
cout << "NO";
return 0;
}
Java
// Java code for the above approach:
import java.util.*;
// Function to find if target[] can be reached
class GFG {
static boolean createTarget(int[] target)
{
// Initialise size of target array
int n = target.length;
// Initialise variable to store
// sum of values
int sum = 0;
// Initialise variable to store
// last sum
int lastSum = 0;
// Initialise a max-heap to keep track
// of the maximum element
PriorityQueue maxHeap = new PriorityQueue();
for (int i = 0; i < target.length; i++)
// we are using negative values as we want to remove the maximum element
// from the priority queue, however, by default the minimum element i removed using poll()
maxHeap.add(-1 * target[i]);
// Start traversing to find the sum
for (int i = 0; i < n; i++)
sum += target[i];
// While heap has element traverse
while (true)
{
// Update last sum with
// maximum value of heap and also
//remove the maximum value from heap
lastSum = -1 * maxHeap.poll();
// Update sum of values
sum -= lastSum;
// If either sum or last sum is
// equal to 1, then
// target array possible
if (lastSum == 1 || sum == 1)
{
return true;
}
// If last sum becomes less than
// sum or if sum becomes equal
// to 0 or if difference of last
// sum and sum becomes 0
if (lastSum <= sum || sum == 0 )
{
return false;
}
// update lastsum and sum
lastSum = lastSum - sum;
sum += lastSum;
// Push last sum into the queue
maxHeap.add(-1 * lastSum);
}
}
// Driver code
public static void main(String[] args) {
int N = 2;
int[] target = {2, 3};
boolean ans = createTarget(target);
if (ans)
System.out.println("YES");
else
System.out.println("NO");
}
}
// This code is contributed by phasing17
Python3
# python3 code for the above approach:
from queue import PriorityQueue
# Function to find if target[] can be reached
def createTarget(target):
# Initialise size of target array
n = len(target)
# Initialise variable to store
# sum of values
sum = 0
# Initialise variable to store
# last sum
lastSum = 0
# Initialise a max-heap to keep track
# of the maximum element
maxHeap = PriorityQueue()
for itm in target:
maxHeap.put(-itm)
# Start traversing to find the sum
for i in range(0, n):
sum = sum + target[i]
# While heap has element traverse
while True:
# Update last sum with
# maximum value of heap
lastSum = -maxHeap.get()
# Pop the maximum element
# of the heap
# Update sum of values
sum = sum - lastSum
# If either sum or last sum is
# equal to 1, then
# target array possible
if (lastSum == 1 or sum == 1):
# Return true
return True
# If last sum becomes less than
# sum or if sum becomes equal
# to 0 or if difference of last
# sum and sum becomes 0
if (lastSum < sum or sum == 0
or lastSum - sum == 0):
# Return false
return False
# Update last sum
lastSum = lastSum - sum
# Update sum
sum = sum + lastSum
# Push last sum into the queue
maxHeap.put(-lastSum)
# Driver code
if __name__ == "__main__":
N = 2
target = [2, 3]
ans = createTarget(target)
if (ans):
print("YES")
else:
print("NO")
# This code is contributed by rakeshsahni
true
时间复杂度: O(N * log(N) + (K / N * log(N))),其中 K 是数组的最大元素。
辅助空间: O(N)