zoukankan      html  css  js  c++  java
  • 698. Partition to K Equal Sum Subsets 数组分成和相同的k组

    [抄题]:

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into knon-empty subsets whose sums are all equal.

    Example 1:

    Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
    Output: True
    Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    dfs中的cc是:组数k直接等于1

    dfs的退出条件是:cur_sum == target

    [思维问题]:

    不懂“是否”题为啥要用dfs:这一步能不能、下一步能不能每个元素都要算到,所以用boolean DFS

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    [一句话思路]:

    DFS扩展的依据是:下一步没有访问过 visited = f,就设置visited = t &回溯。中间要直接return,否则后面没法做。

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. dfs的target直接写成target就行了,就是个参数

    [二刷]:

    1. dfs的start直接写成start就行了,就是个参数 traverse中要变成i + 1

    [三刷]:

    找到k组之后,继续找k - 1 组,变量变化之后就要控制它的最后值 是否为0或1 了

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    有变量k的次数递减,就必须写退出条件。DFS最重要的反而是退出条件

    [复杂度]:Time complexity: O(n) Space complexity: O()

    [算法思想:迭代/递归/分治/贪心]:

    [关键模板化代码]:

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

     [潜台词] :

    class Solution {
        public boolean canPartitionKSubsets(int[] nums, int k) {
            int sum = 0;
            
            //ini: get sum
            for (int num : nums) sum += num;
            int[] visited = new int[nums.length];
            
            //cc: k == 1
            if (k == 1) return true;
            if (k <= 0 || sum % k != 0) return false;
            
            //canPartition
            return canPartition(0, nums, visited, 0, k, sum / k);
        }
        
        public boolean canPartition(int start, int[] nums, int[] visited, int curSum, int k, int target) {
            if(k==1) return true;
            
            //exit :curSum == target
            if (curSum == target) return canPartition(0, nums, visited, 0, k - 1, target);
            
            //backtracing
            for (int i = start; i < nums.length; i++) {
                if (visited[i] == 0) {
                    visited[i] = 1;
                    //do not return directly
                    if(canPartition(i + 1, nums, visited, curSum + nums[i], k, target)) return true;
                    visited[i] = 0;
                }
            }
            
            return false;
        }
    }
    View Code
  • 相关阅读:
    win10如何在局域网中设置一台电脑的固定ip地址
    智能电视软件安装(WIFI上网)
    路由器连接宽带(成功上网步骤方法)
    FastReport.Net使用:[5]主从表
    FastReport.Net使用:[4]分组
    FastReport.Net使用:[3]简单报表一
    FastReport.Net使用:[2]添加MSSQL数据源一
    FastReport.Net使用:[1]屏蔽打印对话框
    如何配置FastReport.Net环境
    如何安装使用FastReport
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9375967.html
Copyright © 2011-2022 走看看