📌  相关文章
📜  删除元素,使得 Array 不能被划分为两个总和相等的子集

📅  最后修改于: 2022-05-13 01:56:12.800000             🧑  作者: Mango

删除元素,使得 Array 不能被划分为两个总和相等的子集

给定一个N大小的数组arr[] ,任务是删除一个元素,使得该数组不能分成两个总和相等的组。

注意:如果不需要删除元素,则返回 -1。

例子:

方法:问题可以通过使用动态规划来解决 基于以下观察的方法:

请按照以下步骤解决问题:

  • 创建一个大小为(sum/2 + 1)*(N+1)的二维数组dp[][] 。这样每个填写的条目都具有以下属性:
    • 如果{arr[0], arr[1], ..arr[j-1]}的子集总和等于i ,则dp[j][i] = true
    • 否则 dp[i][j] = false。
  • 现在,如果dp[N+1][sum/2+1]为真,则在该行上迭代一个循环并找到dp[N][(sum – arr[i]) / 2] = false,然后返回该索引中的元素。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
int removeElement(int arr[], int N)
{
    // Variable to store the sum
    // of the array
    int sum = 0;
    for (int i = 0; i < N; i++) {
        sum += arr[i];
    }
 
    // If sum is odd,
    // it is impossible to divide
    if (sum % 2 == 1) {
        return -1;
    }
 
    // Value needed to find whether
    // it have a subset or not
    int target = sum / 2;
 
    vector > dp(N + 1,
                 vector(target + 1));
 
    // Initializing the first column with 0
    for (int i = 0; i <= N; i++) {
        dp[i][0] = 1;
    }
   
    // Fill the table in
    // bottom up manner
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= target; j++) {
            if (arr[i - 1] <= j) {
                dp[i][j] = dp[i - 1][j]
                  || dp[i - 1][j - arr[i - 1]];
            }
            else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
   
    // If the last element of last row
    // and column is true
    if (dp[N][target] == 1) {
        for (int i = 0; i < N; i++) {
            if (arr[i] % 2
              || dp[N][(sum - arr[i]) / 2]
                == 0) {
                return arr[i];
            }
        }
    }
   
    // If no element is returned, return 0
    return -1;
}
 
// Driver Code
int main()
{
    int arr[] = { 6, 3, 9, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << removeElement(arr, N);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
public class GFG {
 
  static int removeElement(int arr[], int N)
  {
 
    // Variable to store the sum
    // of the array
    int sum = 0;
    for (int i = 0; i < N; i++) {
      sum += arr[i];
    }
 
    // If sum is odd,
    // it is impossible to divide
    if (sum % 2 == 1) {
      return -1;
    }
 
    // Value needed to find whether
    // it have a subset or not
    int target = sum / 2;
 
    boolean dp[][] = new boolean[N + 1][target + 1];
 
    // Initializing the first column with 0
    for (int i = 0; i <= N; i++) {
      dp[i][0] = true;
    }
 
    // Fill the table in
    // bottom up manner
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= target; j++) {
        if (arr[i - 1] <= j) {
          dp[i][j] = dp[i - 1][j]
            || dp[i - 1][j - arr[i - 1]];
        }
        else {
          dp[i][j] = dp[i - 1][j];
        }
      }
    }
 
    // If the last element of last row
    // and column is true
    if (dp[N][target] == true) {
      for (int i = 0; i < N; i++) {
        if (arr[i] % 2 == 1
            || dp[N][(sum - arr[i]) / 2] == false) {
          return arr[i];
        }
      }
    }
 
    // If no element is returned, return 0
    return -1;
  }
 
  // Driver Code
  public static void main(String args[])
  {
    int arr[] = { 6, 3, 9, 12 };
    int N = arr.length;
 
    System.out.println(removeElement(arr, N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python3
# Python3 program to implement
# the above approach
 
# Function to remove the element
def removeElement(arr, N):
   
    # variable to store the sum of the array
    sums = 0
    for i in range(N):
        sums += arr[i]
         
    # if sum is odd, it is impossible
    # to divide
    if sums % 2 == 1:
        return -1
       
    # value reqd to find whether it has
    # a subset or not
    target = sums // 2
    dp = []
    for i in range(N + 1):
        l1 = [False] * (target + 1)
        dp.append(l1)
         
    # initializing the first column
    for i in range(N + 1):
        dp[i][0] = 1
         
    # fill the table in the
    # bottom up manner
    for i in range(1, N + 1):
        for j in range(1, target + 1):
            if arr[i - 1] <= j:
                dp[i][j] = dp[i - 1][j] | dp[i - 1][j - arr[i - 1]]
            else:
                dp[i][j] = dp[i - 1][j]
                 
    # if the last element of last row
    # and column is true
    if dp[N][target] == 1:
        for i in range(N):
            if (arr[i] % 2) or dp[N][(sums - arr[i]) // 2] == 0:
                return arr[i]
               
    # if no element is returned, return 0
    return -1
 
# Driver Code
arr = [6, 3, 9, 12]
N = len(arr)
print(removeElement(arr, N))
 
# This code is contributed by phasing17


C#
// C# program for the above approach
using System;
 
public class GFG{
 
  static int removeElement(int[] arr, int N)
  {
 
    // Variable to store the sum
    // of the array
    int sum = 0;
    for (int i = 0; i < N; i++) {
      sum += arr[i];
    }
 
    // If sum is odd,
    // it is impossible to divide
    if (sum % 2 == 1) {
      return -1;
    }
 
    // Value needed to find whether
    // it have a subset or not
    int target = sum / 2;
 
    bool[,] dp = new bool[N + 1, target + 1];
 
    // Initializing the first column with 0
    for (int i = 0; i <= N; i++) {
      dp[i, 0] = true;
    }
 
    // Fill the table in
    // bottom up manner
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= target; j++) {
        if (arr[i - 1] <= j) {
          dp[i, j] = dp[i - 1, j]
            || dp[i - 1, j - arr[i - 1]];
        }
        else {
          dp[i, j] = dp[i - 1, j];
        }
      }
    }
 
    // If the last element of last row
    // and column is true
    if (dp[N, target] == true) {
      for (int i = 0; i < N; i++) {
        if (arr[i] % 2 == 1
            || dp[N, (sum - arr[i]) / 2] == false) {
          return arr[i];
        }
      }
    }
 
    // If no element is returned, return 0
    return -1;
  }
 
  // Driver Code
  static public void Main (){
 
    int[] arr = { 6, 3, 9, 12 };
    int N = arr.Length;
 
    Console.Write(removeElement(arr, N));
  }
}
 
// This code is contributed by hrithikgarg03188.


Javascript


输出
3

时间复杂度: O(sum*N)
辅助空间: O(sum*N)