面试题 16.11. 跳水板

题目链接

面试题 16.11. 跳水板

题目分析

这个题其实就是给了我们两种长度为shoter和longer的板子,要求我们合理的对其进行搭配,只要使用到的板子个数为k即可。
题目要求返回的长度是从小到大排列的。
那么我们可以从最短的进行入手了,因为k个最短的板子肯定是会构成返回值中的第一个数,所以我们拿这个作为基数。
然后我们开始逐渐将短板一块一块换成长板,这样构成的长度绝对就是递增的了。
这个题要注意两个边界值:

  • k为0的时候,我们需要返回空数组。
  • shorter和longer相等的时候,会产生相同的值,需要去重。

代码实现

代码一

代码一是我自己一开始做的,利用list存放我们得到的值,也保证了其相对顺序。然后使用set来进行去重。

class Solution {
    public int[] divingBoard(int shorter, int longer, int k) {
        if(k == 0){
            return new int[0];
        }
        List<Integer> list = new ArrayList<>();
        Set<Integer> set = new HashSet<>();
        int sum = shorter;
        sum = sum * k;
        list.add(sum);
        set.add(sum);
        for(int i = 0; i < k; i++){
            sum = sum - shorter + longer;
            if(set.contains(sum)){
                continue;
            }
            list.add(sum);
        }
        int[] res = new int[list.size()];
        for(int i = 0; i < list.size(); i++){
            res[i] = list.get(i);
        }
        return res;
    }
}

代码二

留意到这个题其实它的总长度是已知的,我们全部短板作为单独的一项,后面进行了k项的替换,所以总长度是k+1。因此我们可以抛弃list这个容器。
同时我们也留意到重复的情况只有shorter和longer相等的时候才会出现,模板的总个数是写死的,1+1+1 != 1+2,所以当我们遇到两者相等的时候,直接返回短板之和即可。

class Solution {
    public int[] divingBoard(int shorter, int longer, int k) {
        if(k == 0){
            return new int[0];
        }
        if (shorter == longer){
            return new int[]{shorter * k};
        }
        int[] res = new int[k + 1];
        int sum = shorter;
        sum = sum * k;
        res[0] = sum;
        for(int i = 0; i < k; i++){
            sum = sum - shorter + longer;
            res[i+1] = sum;
        }
        return res;
    }
}

总结

题目不难 ,但是优化很难。

原文地址:https://www.cnblogs.com/ZJPaang/p/13265105.html