📌  相关文章
📜  检查是否存在具有给定总和的非相邻对

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

检查是否存在具有给定总和的非相邻对

给定一个数组nums [ ] 和一个整数目标。查找nums [ ] 中是否存在整数组合,使得它们的和等于目标,并且这些元素在原始数组中都不相邻。

示例

方法:可以使用动态编程按照以下步骤解决问题:

  • dp[i][j]:创建一个 2-d dp 数组,存储在考虑数组中的前 i 个元素后是否有可能获得恰好 j 的总和。
  • 在给定索引 i 和给定总和 j 处,可能有两种情况:
    • 要么我们可以包含当前数字 nums[i],要么不包含。
    • 如果我们不包括当前数字,我们只需回顾 dp 的上一行。
    • 如果我们确实包含当前数字,我们必须回顾 dp 数组中的两行,因为不能选择相邻的元素。
    • 因此,一旦我们选择了元素 i,我们就可以忽略元素 i-1,因为它不能被采用。
  • 基本情况:
    • 最初用 false 初始化布尔 dp 表。
    • 然后,在第一列中填写 true,因为总和 0 始终可以通过不取任何元素来实现。
    • 同时用真值填充dp[i][nums[i]] ,这表明我们可以在考虑数组中的前 i 个元素后得到 nums[i] 的总和(很明显只取索引 i 处的元素) .
  • 过渡状态
    • 案例1: dp[i][j] = dp[i – 1][j] || dp[i][j]
      • 检查上一行的值
      • 如果它是真的,那么我们可以通过将元素直到最后一行来使子集总和等于目标,
      • 所以也让 dp[i][j] 为真
    • 案例2: dp[i][j] = dp[i – 2][j – nums[i]] || dp[i][j]
      • 检查我们是否将当前元素 nums[i] 添加到当前行 - 2(因为它不相邻)dp 表,并使总和等于目标。

插图:

下面是上述方法的实现:

C++
// C++ program to implement above approach
 
#include 
using namespace std;
 
bool subsetSumNonAdjacent(
    vector& nums, int target)
{
    // size of the array
    int n = nums.size();
 
    // Boolean dp table fill with false
    vector > dp(
        n, vector(target + 1, false));
 
    // Base Case
    // Initialize dp[i][0]= true
    // as 0 can always be achieved
    // by not taking anything
    for (int i = 0; i < n; i++) {
        dp[i][0] = true;
    }
 
    // Initialize dp[i][nums[i]]= true
    // as nums[i] can always be achieved
    // by taking only element
    // at index i that is nums[i]
    for (int i = 0; i < n; i++) {
        dp[i][nums[i]] = true;
    }
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= target; j++) {
 
            // check if we can take previous row
            if (i - 1 >= 0) {
                dp[i][j]
                    = dp[i - 1][j] || dp[i][j];
            }
 
            // check for row-2
            if (i - 2 >= 0 && j >= nums[i]) {
                dp[i][j]
                    = dp[i - 2][j - nums[i]]
                      || dp[i][j];
            }
        }
    }
 
    return dp[n - 1][target];
}
 
// Driver code
int main()
{
    vector nums = { 1, 2, 2, 3 };
    int target = 4;
    cout << boolalpha
         << subsetSumNonAdjacent(nums, target);
    return 0;
}


Java
// Java Program of the above approach.
import java.util.*;
class GFG {
 
  static boolean subsetSumNonAdjacent(int[] nums, int target)
  {
 
    // size of the array
    int n = nums.length;
 
    // Boolean dp table fill with false
    boolean[][] dp = new boolean[n][target + 1];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < target + 1; j++) {
        dp[i][j] = false;
      }
    }
 
    // Base Case
    // Initialize dp[i][0]= true
    // as 0 can always be achieved
    // by not taking anything
    for (int i = 0; i < n; i++) {
      dp[i][0] = true;
    }
 
    // Initialize dp[i][nums[i]]= true
    // as nums[i] can always be achieved
    // by taking only element
    // at index i that is nums[i]
    for (int i = 0; i < n; i++) {
      dp[i][nums[i]] = true;
    }
 
    for (int i = 0; i < n; i++) {
      for (int j = 0; j <= target; j++) {
 
        // check if we can take previous row
        if (i - 1 >= 0) {
          dp[i][j] = dp[i - 1][j] || dp[i][j];
        }
 
        // check for row-2
        if (i - 2 >= 0 && j >= nums[i]) {
          dp[i][j] = dp[i - 2][j - nums[i]]
            || dp[i][ j];
        }
      }
    }
 
    return dp[n - 1][target];
  }
 
  // Driver Code
  public static void main(String args[])
  {
    int[] nums = { 1, 2, 2, 3 };
    int target = 4;
    System.out.print(subsetSumNonAdjacent(nums, target));
  }
}
 
// This code is contributed by code_hunt.


Python3
# Python program to implement above approach
def subsetSumNonAdjacent(nums,target):
 
    # size of the array
    n = len(nums)
 
    # Boolean dp table fill with false
    dp = [[False]*(target+1)]*n
 
    # Base Case
    # Initialize dp[i][0]= true
    # as 0 can always be achieved
    # by not taking anything
    for i in range(n):
        dp[i][0] = True
 
    # Initialize dp[i][nums[i]]= true
    # as nums[i] can always be achieved
    # by taking only element
    # at index i that is nums[i]
    for i in range(n):
        dp[i][nums[i]] = True
 
    for i in range(n):
        for j in range(target+1):
 
            # check if we can take previous row
            if (i - 1 >= 0):
                dp[i][j] = dp[i - 1][j] or dp[i][j]
 
            # check for row-2
            if (i - 2 >= 0 and j >= nums[i]):
                dp[i][j] = dp[i - 2][j - nums[i]] or dp[i][j]
 
    return dp[n - 1][target]
 
# Driver code
nums = [ 1, 2, 2, 3 ]
target = 4
print(subsetSumNonAdjacent(nums, target))
 
# This code is contributed by shinjanpatra


C#
// C# program to implement above approach
using System;
class GFG {
 
  static bool subsetSumNonAdjacent(int[] nums, int target)
  {
     
    // size of the array
    int n = nums.Length;
 
    // Boolean dp table fill with false
    bool[, ] dp = new bool[n, target + 1];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < target + 1; j++) {
        dp[i, j] = false;
      }
    }
 
    // Base Case
    // Initialize dp[i][0]= true
    // as 0 can always be achieved
    // by not taking anything
    for (int i = 0; i < n; i++) {
      dp[i, 0] = true;
    }
 
    // Initialize dp[i][nums[i]]= true
    // as nums[i] can always be achieved
    // by taking only element
    // at index i that is nums[i]
    for (int i = 0; i < n; i++) {
      dp[i, nums[i]] = true;
    }
 
    for (int i = 0; i < n; i++) {
      for (int j = 0; j <= target; j++) {
 
        // check if we can take previous row
        if (i - 1 >= 0) {
          dp[i, j] = dp[i - 1, j] || dp[i, j];
        }
 
        // check for row-2
        if (i - 2 >= 0 && j >= nums[i]) {
          dp[i, j] = dp[i - 2, j - nums[i]]
            || dp[i, j];
        }
      }
    }
 
    return dp[n - 1, target];
  }
 
  // Driver code
  public static void Main()
  {
    int[] nums = { 1, 2, 2, 3 };
    int target = 4;
    Console.Write(subsetSumNonAdjacent(nums, target));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出
true

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