题解 | #数组分组#

数组分组

https://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86

import java.util.Scanner;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
** 思路: 将输入的数字分成两组并且相等,每组为sum/2; 这样考虑的话会在等于0的时候有特殊判断:
	(1)当前递归成立的结果是否为空,如果为空,剩下的数字中是否是15的倍数
	(2)当前递归成立的结果结果满足要求,剩下的数组是否满足要求。
	(3)这里可以通过求乘积的方法。也可以选择计数统计的方法。
	(4)这道题上来没有想到3倍数一组 5 倍数这样的分组方法。所以,就在上面的思路进行了优化。
	(5) 利用一个小的字典dict_cnt_flag:dict_cnt_flag[0]表示3倍数的个数,dict_cnt_flag[1]表示5倍数的个数,dict_cnt_flag[2]表示当前求的数组是否存在3的倍数,dict_cnt_flag[3]表示当前求的数组是否是5的倍数。
	(6)每次递归的时候对dict_cnt_flag[2] 和 dict_cnt_flag[3]进行判断,如果当前结果集存在3或5的倍数,并且新进来的数字是3或者5的倍数时候,新进来的数字就不再添加。如果新进来3或5的倍数时,把对应标志为修改为3 和 5.
	(7)每次回溯的时候弹出stack(stack用来判断满足条件的最终结果是否为空),如果加入的数字是3或5的倍数回溯的时候修改为0.
***/
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) throws IOException {
//    Scanner in = new Scanner(System.in);
    BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
    String input;
    while ((input = read.readLine()) != null){
      int len = Integer.parseInt(input);
      int[] nums = new int[len];
      String[] strnums = read.readLine().split(" ");
      int[] visited = new
          int[len]; //如果是5的倍数放入了标记5, 如果是3的倍数放入标记3,其他1
      int total = 0;
      int[] dict_cnt_flag = new int[4];
      for (int i = 0; i < len; i++) {
        nums[i] = Integer.parseInt(strnums[i]);
        total += nums[i];
        if(nums[i] != 0){
          if(nums[i] % 3 == 0){
            dict_cnt_flag[0]++;
          }
          if(nums[i] % 5 == 0){
            dict_cnt_flag[1]++;
          }
        }
      }
      if (Math.abs(total) % 2 != 0) {
        System.out.println("false");
      } else {
        int target = total / 2;
        Stack<Integer> stack = new Stack<>();
        boolean ans = dfs(nums, 0, 0, target, visited, stack, dict_cnt_flag);
        System.out.println(ans==true ? "true" : "false");

      }
    }
  }

  public static boolean dfs(int[] nums, int index, int tmp, int target,
                            int[] visited, Stack<Integer> stack,int[] dict_cnt) {
    if (index >= nums.length && target == tmp) {
      if(stack.isEmpty()){
        return (dict_cnt[0] > 0 && dict_cnt[1] > 0) ? false : true;
      } else {
        int cnt_3 = dict_cnt[0];
        int cnt_5 = dict_cnt[1];
        return (cnt_3 > 0 && cnt_5 > 0) ? false : true;
      }
    }  else if (index >= nums.length && target != tmp) {
      return false;
    }

    boolean p1 = false, p2 = false, p3 = false, p4 = false;
    if ((nums[index] % 5 == 0 && dict_cnt[2] == 3)) {
      visited[index] = 1;
      p1 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
    } else if (nums[index] % 3 == 0 && dict_cnt[3] == 5) {
      visited[index] = 1;
      p2 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
    } else {
      visited[index] = 1;
      p3 = dfs(nums, index + 1, tmp, target, visited, stack,dict_cnt);
      stack.push(nums[index]);
      if(nums[index] % 3 == 0 ){
        dict_cnt[0]--;
        dict_cnt[2] = 3;
      } else if(nums[index] % 5 == 0){
        dict_cnt[1]--;
        dict_cnt[3] = 5;
      }
      p4 = dfs(nums, index + 1, tmp + nums[index], target, visited, stack, dict_cnt);
      int pop = stack.pop();
      if(pop % 3 == 0 ){
        dict_cnt[0]++;
        dict_cnt[2] = 0;
      } else if(pop % 5 == 0){
        dict_cnt[1]++;
        dict_cnt[3] = 0;
      }
    }
    visited[index] = 0;
    return p1 || p2 || p3 || p4;
  }


}

全部评论

相关推荐

死在JAVA的王小美:哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,我也是,让我免了一轮,但是硬气拒绝了
点赞 评论 收藏
分享
牛客717484937号:双飞硕没实习挺要命的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务