【问题标题】:Divide an array into 2 groups by certain a conditions, using recursion使用递归将数组按特定条件分成 2 组
【发布时间】:2018-11-13 02:49:54
【问题描述】:

给定任务:“编写名为 'mysplit' 的函数,该函数获取一个 int 数组并调用 名为“MySplit”的递归方法。函数 MySplit 需要检查是否 当前数组可以分为 2 组,它们遵循以下条件:

*每组的总和必须相等。

*每个数字在每个组中仅出现一次(此子句旨在防止用户添加/复制数字以使两个组=第一个子句相等)。

*所有能被5整除的数必须在同一组内。

*所有可以被 3(而不是 5)整除的数字都必须在第二组中。

我已经编写了这段代码,但是走到了死胡同。我没有完成任务的前 2 个子句,并且想不出将它插入到我的代码中的方法。

这是我写的代码:

public static boolean mySplit(int[] nums)
{
    return MySplit(nums,0,0,0);
}

public static boolean MySplit(int[]arr,int result_5,int result_3,int pointer)//2 groups: 'result_5' & 'result_3' and pointer to iterate through an array
{
    if(arr[pointer]%5==0)
    {
        return MySplit(arr,result_5+arr[pointer],result_3,pointer++);
    }
    else if(arr[pointer]%3==0)
    {
        return MySplit(arr,result_5,result_3+arr[pointer],pointer++);
    }

}

*编辑: **示例:

mySplit([1,1])==>真

mySplit([1,1,1])==>假​​

mySplit([2,4,2])==>真

mySplit([5,21,8,15,7])==>真

mySplit([15,10,5])==>假​​

mySplit([15,8,7])==>真

【问题讨论】:

标签: java arrays recursion


【解决方案1】:

注意 cmets。如果需要更多说明,请随时询问:

public static void main(String[] args) {

    System.out.println(mySplit(1,1));           //true
    System.out.println(mySplit(1,1,1));         //false
    System.out.println(mySplit(2,4,2));         //true
    System.out.println(mySplit(5,21,8,15,7));   //true
    System.out.println(mySplit(15,0,5));        //false
    System.out.println(mySplit(15,8,7));        //true
}

public static boolean mySplit(int...nums)
{
    List<Integer> groupA = new ArrayList<>(); //initialized by all numbers divided by 5
    List<Integer> groupB = new ArrayList<>(); //initialized by all other numbers divided by 3
    List<Integer> groupC = new ArrayList<>(); //initialized by all other numbers

    for(int number : nums) {
        if((number % 5) == 0 ) {
            groupA.add(number);
        }else if ((number % 3) == 0 ) {
            groupB.add(number);
        }else {
            groupC.add(number);
        }
    }

    return mySplit(groupA, groupB, groupC);
}

private static boolean mySplit(List<Integer> groupA, List<Integer> groupB, List<Integer> groupC) {

    if(groupC.size() == 0 ) { //no more numbers to add
        return  sumList(groupA) == sumList(groupB);
    }

    int next = groupC.get(0);
    groupC.remove(0);

    //make a new group A which includes next 
    List<Integer> newGroupA = new ArrayList<>(groupA);
    newGroupA.add(next);

    //make a new group B which includes next 
    List<Integer> newGroupB = new ArrayList<>(groupB);
    newGroupB.add(next);

    //check with new A and B. Make a defensive copy of groupC 
    //to prevent changes in groupC 
    if( mySplit(newGroupA, groupB, new ArrayList(groupC))) {

        return true;
    //check with A and new B
    }else if( mySplit(groupA, newGroupB, new ArrayList(groupC))) {

        return true;
    }

    return false; //equality not found 
}

//sum a list 
private static int sumList(List<Integer> list) {

    /* a pre java 8 version
        int sum = 0;
        for( int i : list ) {  sum += i;}
        return sum;
    */
    return list.stream().mapToInt(Integer::intValue).sum();
}

您可以将mySplit(int...nums)的签名更改为mySplit(int[] nums)并通过mySplit(new int[]{2,4,2})调用它

【讨论】:

  • 带有流和for 循环的递归解决方案?
  • 是的。使用辅助方法(有或没有流)没有任何问题。 For 循环是一种有效的工具,在递归方法中很常见1234
  • 学术环境中的递归与软件工程环境中的递归不同。这个脑力练习的重点是以递归方式制定归约步骤(即我们减少剩余要处理的输入大小的步骤)。这更像是一种混合方法,因为您为此目的部分使用了迭代。
【解决方案2】:

这是我想出的:

public static void main(String[] args)
{
    System.out.println(mySplit(new int[] { 1, 1 })); // ==>true

    System.out.println(mySplit(new int[] { 1, 1, 1 })); // ==>false

    System.out.println(mySplit(new int[] { 2, 4, 2 })); // ==>true

    System.out.println(mySplit(new int[] { 5, 21, 8, 15, 7 })); // ==>true

    System.out.println(mySplit(new int[] { 15, 10, 5 })); // ==>false

    System.out.println(mySplit(new int[] { 15, 8, 7 })); // ==>true
}

public static boolean mySplit(int[] nums)
{
    if (nums.length == 0)
        return false;

    return mySplit(nums, 0, 0, 0);
}

private static boolean mySplit(int[] nums, int i, int groupA, int groupB)
{
    if (i == nums.length)
        return groupA == groupB; // At the end, check if the sum of each group is equal.

    if (nums[i] % 5 == 0)
        return mySplit(nums, i + 1, groupA + nums[i], groupB); // All the numbers that can be divided by 5 must be in the same group (Group A).

    if (nums[i] % 3 == 0 && nums[i] % 5 != 0)
        return mySplit(nums, i + 1, groupA, groupB + nums[i]); // All the numbers that can be divided by 3 (and not by 5) must be in the second group (Group B).

    return mySplit(nums, i + 1, groupA + nums[i], groupB) || mySplit(nums, i + 1, groupA, groupB + nums[i]);
}

【讨论】:

    猜你喜欢
    • 2020-07-25
    • 1970-01-01
    • 2022-01-08
    • 2016-12-13
    • 2015-06-25
    • 2019-05-31
    • 2018-05-19
    • 1970-01-01
    • 2020-10-01
    相关资源
    最近更新 更多