Leetcode 279 完全平方数

1.题目

在这里插入图片描述

解法:(BFS队列实现)

这种题目特点就是:你同时有好多的选项可以选择。
思想就是:列举出所有可能组成该数的完全平方数,那么一个点就对应arr.size()的选择,使用队列记录每次减之后的结果,使用count记录减的次数,寻找第一个减为0的数。

class oneVal{
    int res = 0;
    int count = 0;
    public  oneVal(int r, int c){
        res = r;
        count = c;
    }
}

class Solution {
    public int numSquares(int n) {
            int res = 0;
            oneVal tmp = null;
            ArrayList<Integer> arr = new ArrayList<>();
            int i = 1;
            while(i * i <= n){
                arr.add(i*i);
                ++i;
            }
            Queue<oneVal> queue = new LinkedList<oneVal>();
            queue.offer(new oneVal(n, 0));
            while(!queue.isEmpty()){
                tmp = queue.poll();
                for(i = arr.size()-1; i >= 0; i--){
                    res =  tmp.res - arr.get(i);
                    if(res > 0){
                       queue.offer(new oneVal(res, tmp.count+1));
                    }else if(res == 0){
                        return tmp.count+1;
                    }else{
                        continue;
                    }
                }
            }
            return -1;
    }
}

(1)一次性将所有的余数 对应 这个平方数,这样的话,每次level就可以统一计算。
(2)余数如果小于了平方数,那么就是不合理的,因为我要找到比我小的完全平方数。


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

class Solution {
    public int numSquares(int n) {

        ArrayList<Integer> square_nums = new ArrayList<>();
        for (int i = 1; i * i <= n; ++i) {
            square_nums.add(i * i);
        }

        Set<Integer> queue = new HashSet<Integer>();
        queue.add(n);

        int level = 0;
        while (queue.size() > 0) {
            level += 1;
            Set<Integer> next_queue = new HashSet<Integer>();
            // 从队列出来的每一个数都会和完全平方数进行比对,所以只要相等,那就结束
            for (Integer remainder : queue) {
                for (Integer square : square_nums) {
                    // 因为Integer类,所以判断内容相等用equals
                    if (remainder.equals(square)) {
                        return level;
                    // 都比余数大了,那后面的数,就没必要比了(从小到大)
                    } else if (remainder < square) {
                        break;
                    } else {
                        // 因为得到的余数和原来的不一样,所以就使用了新的quque
                        next_queue.add(remainder - square);
                    }
                }
            }
            queue = next_queue;

        }
        return level;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值