给定一个数组arr[] ,任务是找到元素总和小于或等于其索引总和的最大子集的长度(基于 1 的索引)。
例子:
Input: arr[] = {1, 7, 3, 5, 9, 6, 6}
Output: 5
Explanation:
Largest Subset is {1, 3, 5, 6, 6}
Sum of indexes = 1 + 3 + 4 + 6 + 7 = 21
Sum of elements = 1 + 3 + 5 + 6 + 6 = 21
Input: arr[] = {4, 1, 6, 7, 8, 2}
Output: 3
天真的方法:
解决问题的最简单方法是生成所有可能的子集并计算元素总和小于或等于其各自索引之和的子集的长度。
时间复杂度: O(N*2 N )
辅助空间: O(N)
有效的方法:
请按照以下步骤解决问题:
- 迭代所有索引,只考虑那些值大于或等于存储在其中的各个值的值的索引。
- 不断更新上一步得到的差值的总和。
- 对于剩下的元素,用它们各自的索引存储它们的差异。对差异进行排序。
- 将元素一一包含在子集中,并从总和中减去差值。继续包含,直到遇到与其索引的差值超过剩余总和的元素或已包含所有数组元素。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to find the length
// of the longest subset
int findSubset(int* a, int n)
{
// Stores the sum of differences
// between elements and
// their respective index
int sum = 0;
// Stores the size of
// the subset
int cnt = 0;
vector v;
// Iterate over the array
for (int i = 1; i <= n; i++) {
// If an element which is
// smaller than or equal
// to its index is encountered
if (a[i - 1] - i <= 0) {
// Increase count and sum
sum += a[i - 1] - i;
cnt += 1;
}
// Store the difference with
// index of the remaining
// elements
else {
v.push_back(a[i - 1] - i);
}
}
// Sort the differences
// in increasing order
sort(v.begin(), v.end());
int ptr = 0;
// Include the differences while
// sum remains positive or
while (ptr < v.size()
&& sum + v[ptr] <= 0) {
cnt += 1;
ptr += 1;
sum += v[ptr];
}
// Return the size
return cnt;
}
// Driver Code
int main()
{
int arr[] = { 4, 1, 6, 7,
8, 2 };
int n = sizeof(arr)
/ sizeof(arr[0]);
// Function Calling
cout << findSubset(arr, n)
<< endl;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to find the length
// of the longest subset
public static int findSubset(int[] a, int n)
{
// Stores the sum of differences
// between elements and
// their respective index
int sum = 0;
// Stores the size of
// the subset
int cnt = 0;
Vector v = new Vector<>();
// Iterate over the array
for(int i = 1; i <= n; i++)
{
// If an element which is
// smaller than or equal
// to its index is encountered
if (a[i - 1] - i <= 0)
{
// Increase count and sum
sum += a[i - 1] - i;
cnt += 1;
}
// Store the difference with
// index of the remaining
// elements
else
{
v.add(a[i - 1] - i);
}
}
// Sort the differences
// in increasing order
Collections.sort(v);
int ptr = 0;
// Include the differences while
// sum remains positive or
while (ptr < v.size() &&
sum + v.get(ptr) <= 0)
{
cnt += 1;
ptr += 1;
sum += v.get(ptr);
}
// Return the size
return cnt;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 4, 1, 6, 7, 8, 2 };
int n = arr.length;
// Function Calling
System.out.println(findSubset(arr, n));
}
}
// This code is contributed by divyeshrabadiya07
Python3
# Python3 program to implement
# the above approach
# Function to find the length
# of the longest subset
def findSubset(a, n):
# Stores the sum of differences
# between elements and
# their respective index
sum = 0
# Stores the size of
# the subset
cnt = 0
v = []
# Iterate over the array
for i in range(1, n + 1):
# If an element which is
# smaller than or equal
# to its index is encountered
if (a[i - 1] - i <= 0):
# Increase count and sum
sum += a[i - 1] - i
cnt += 1
# Store the difference with
# index of the remaining
# elements
else:
v.append(a[i - 1] - i)
# Sort the differences
# in increasing order
v.sort()
ptr = 0
# Include the differences while
# sum remains positive or
while (ptr < len(v) and
sum + v[ptr] <= 0):
cnt += 1
ptr += 1
sum += v[ptr]
# Return the size
return cnt
# Driver code
if __name__=="__main__":
arr = [ 4, 1, 6, 7, 8, 2 ]
n = len(arr)
# Function calling
print(findSubset(arr, n))
# This code is contributed by rutvik_56
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the length
// of the longest subset
public static int findSubset(int[] a, int n)
{
// Stores the sum of differences
// between elements and
// their respective index
int sum = 0;
// Stores the size of
// the subset
int cnt = 0;
List v = new List();
// Iterate over the array
for(int i = 1; i <= n; i++)
{
// If an element which is
// smaller than or equal
// to its index is encountered
if (a[i - 1] - i <= 0)
{
// Increase count and sum
sum += a[i - 1] - i;
cnt += 1;
}
// Store the difference with
// index of the remaining
// elements
else
{
v.Add(a[i - 1] - i);
}
}
// Sort the differences
// in increasing order
v.Sort();
int ptr = 0;
// Include the differences while
// sum remains positive or
while (ptr < v.Count &&
sum + v[ptr] <= 0)
{
cnt += 1;
ptr += 1;
sum += v[ptr];
}
// Return the size
return cnt;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 4, 1, 6, 7, 8, 2 };
int n = arr.Length;
// Function calling
Console.WriteLine(findSubset(arr, n));
}
}
// This code is contributed by amal kumar choubey
Javascript
输出:
3
时间复杂度: O(N)
空间复杂度: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live