leetcode279-完全平方数

原题

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

示例 1:

输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.

示例 2:

输入: n = 13
输出: 2
解释: 13 = 4 + 9.

解法

思想

以12为例。

这道题确实对时间要求比较严格,如果不过滤掉重复计算的部分会无法通过。

从目标数出发自顶向下:

leetcode279-完全平方数

由已知的目标数出发,减去比它小的平方数,这样一层一层减下去,直到获得0的那一层的层数就是答案。

需要过滤掉数值重复的节点,比如11-4和8-1。

从平方数出发自底向上:

leetcode279-完全平方数

由比已知目标数小的所有平方数出发,每层做一个组合加法,但是有一些地方需要处理:

  1. 遇到数值相等的节点,如1+4和4+1,跳过该节点。
  2. 在组合的时候遇到从一个数开始,加上它就会大于目标数,那么它之后的平方数都可以不做组合了,因为都比它大。

代码

自顶向下:

class Node{
    public int value;
    public int depth;
    public Node(int value,int depth){
        this.value = value;
        this.depth = depth;
    }
}

class Solution {
    public int numSquares(int n) {
        int mark[] = new int[n];
        if(n<4) return n;
        Queue<Node> queue = new LinkedList<>();
        queue.offer(new Node(n,0));
        while(!queue.isEmpty()){
            Node node = queue.poll();
            if(node.value==0) return node.depth; 
            int sqrt = (int)Math.sqrt(node.value);
            for(int i = sqrt; i > 0 ; i--){
                if(mark[node.value-i*i]==0){
                    queue.offer(new Node(node.value-i*i,node.depth+1));
                    mark[node.value-i*i] = 1;
                }
            }

        }
        return -1;
    }
}

自底向上

class Node{
    public int value;
    public int depth;
    public Node(int value,int depth){
        this.value = value;
        this.depth = depth;
    }
}

class Solution {
    public int numSquares(int n) {
        Queue<Node> queue = new LinkedList<>();
        int a = (int)Math.sqrt(n);
        int[] mark = new int[n+1];
        for(int i = a;i>a/2;i--){
            queue.offer(new Node(i*i,1));
            mark[i*i] = 1;
        }

        while(!queue.isEmpty()){
            Node node = queue.poll();
            int value = node.value;
            if(value==n) return node.depth;
            for(int i = 1;i<=a;i++){
                if(value+i*i>n) break;
                if(mark[value+i*i]==1) continue;
                queue.offer(new Node(value+i*i,node.depth+1));
                mark[value+i*i] = 1;
            }
        }
        return -1;
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode279-%e5%ae%8c%e5%85%a8%e5%b9%b3%e6%96%b9%e6%95%b0/

(0)
彭晨涛彭晨涛管理者
上一篇 2019年12月10日 18:05
下一篇 2019年12月12日 18:05

相关推荐

  • leetcode151-翻转字符串里的单词

    原题 给定一个字符串,逐个翻转字符串中的每个单词。 示例 1: 输入: “the sky is blue” 输出: “blue is sky the” 示例 2: 输入: “ he…

    算法 2019年11月22日
    090
  • leetcode435-无重叠区间

    原题 给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。 注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没…

    算法 2020年2月18日
    02440
  • leetcode14-最长公共前缀

    原题 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入: [“flower”,”flow”,”flight”] 输出: “…

    算法 2019年11月18日
    0110
  • leetcode367-有效的完全平方数

    原题 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。 说明: 不要使用任何内置的库函数,如  sqrt。 示例1: …

    算法 2020年1月5日
    0150
  • leetcode705-设计哈希集合

    原题 不使用任何内建的哈希表库设计一个哈希集合 具体地说,你的设计应该包含以下的功能 add(value):向哈希集合中插入一个值。 contains(value) :返回哈希集合…

    算法 2019年12月18日
    0140
  • leetcode232-用栈实现队列

    原题 使用栈实现队列的下列操作: push(x) – 将一个元素放入队列的尾部。 pop() – 从队列首部移除元素。 peek() – 返回队列首部的元素。 empty() – …

    算法 2019年12月13日
    0560
  • leetcode73-矩阵置零

    原题 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。 示例 1: 输入: [   [1,1,1],  …

    算法 2020年5月14日
    0130
  • leetcode7-整数反转

    原题 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例1: 输入: 123 输出: 321 示例2: 输入: -123 输出: -321 示例3: 输…

    算法 2020年2月26日
    0120
  • 程序员面试金典08.11-硬币

    原题(来源Leetcode) 硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007) 示…

    算法 2020年4月23日
    0180
  • leetcode1014-最佳观光组合

    原题 给定正整数数组 A,A[i] 表示第 i 个观光景点的评分,并且两个景点 i 和 j 之间的距离为 j - i。 一对景点(i < j)组成的观光组合的得分为(A[i]…

    算法 2020年6月17日
    01980

发表回复

登录后才能评论