Java 给定一个整数数组和一个和,任务是找出给定数组中是否存在和等于给定和的子集

Java 给定一个整数数组和一个和,任务是找出给定数组中是否存在和等于给定和的子集,java,algorithm,recursion,data-structures,dynamic-programming,Java,Algorithm,Recursion,Data Structures,Dynamic Programming,这是我写的函数 public static boolean existsSum(int[] arr, int n, int sum){ if(sum==0) return true; if(n<=0) return false; if(arr[n-1] == sum) return true;

这是我写的函数

    public static boolean existsSum(int[] arr, int n, int sum){
            if(sum==0)
                return true;
            if(n<=0)
                return false;
            if(arr[n-1] == sum)
                return true;
            if(sum<0)
                return false;
            if(sum<arr[n-1])
                return existsSum(arr, n-1,sum);
            return existsSum(arr, n-1, sum-arr[n-1])  || existsSum(arr, n-1,sum)  ;
        }
公共静态布尔存在(int[]arr,int n,int sum){
如果(总和=0)
返回true;

如果(n注意
||
短路的事实,即在
a | | b
中,如果
a
为真,则不计算
b

|
的两个操作数之间的区别在于
existsSum(arr,n-1,sum arr[n-1])
将当前项“添加”到与总和相加的项列表中,而
existsSum(arr,n-1,sum)
不会

在第一个代码段中,如果
existsSum(arr,n-1,sum-arr[n-1])
为true,则甚至不调用
existsSum(arr,n-1,sum)
。假设我使用数组
[1,2,3]
和和6来调用它。第一个操作数将在每次递归调用时返回true,而无需计算第二个操作数

类似地,在第二个代码段中,
existsSum(arr,n-1,sum)
首先运行,如果为true,则不会调用
existsSum(arr,n-1,sum arr[n-1])
。但是,
existsSum(arr,n-1,sum)
本身很少返回true。我的意思是,对于调用
existsSum(arr,n-1,sum)
要返回true,值
true
必须来自对
existsSum(arr,n-1,sum-arr[n-1])
的递归调用。您可以通过分析不同的分支来验证这一点。(返回true的两个分支是
sum==0
arr[n-1]==sum
。希望您同意这两个分支都是罕见的)这意味着回溯(即调用
existsSum(arr,n-1,sum-arr[n-1])
)肯定会发生在
existsSum(arr,n-1,sum)


但在最坏的情况下,这两个代码段是相同的。

这应该是O(n)

public静态布尔求和存在(int[]in,int-sum){
//您可能只需要对值进行排序,而不复制它。
int[]input=Arrays.copyOf(in,in.length);
数组。排序(输入);
int currentSum=0;
int startIdx=0;
for(int i=0;i总和){
while(currentSum>sum&&startIdx
您能给出一个您正在尝试使用的输入示例吗?子集是连续的吗?简言之,测试用例很弱,两种解决方案都应该给出超出时间限制的结果。
    public static boolean existsSum(int[] arr, int n, int sum){
            if(sum==0)
                return true;
            if(n<=0)
                return false;
            if(arr[n-1] == sum)
                return true;
            if(sum<0)
                return false;
            if(sum<arr[n-1])
                return existsSum(arr, n-1,sum);
            return existsSum(arr, n-1,sum) || existsSum(arr, n-1, sum-arr[n-1])  ;
        }
public static boolean sumExists(int [] in, int sum) {
    //You might be able to get away with just sorting the values and not copying it.
    int [] input = Arrays.copyOf(in, in.length);
    Arrays.sort(input);
    int currentSum = 0;
    int startIdx = 0;
    for (int i = 0; i < input.length; i++) {
        if (currentSum > sum) {
            while (currentSum > sum && startIdx < i) {
                currentSum -= input[startIdx++];
            }
        }

        if (currentSum == sum) {
            return true;
        } 
        currentSum += input[i];
    }
    return false;
}