找到所有数组中消失的数、最小操作次数使数组元素相等、分发饼干

🍅 Java学习路线:搬砖工逆袭Java架构师

🍅 简介:Java领域优质创作者🏆、CSDN哪吒公众号作者✌ 、Java架构师奋斗者💪

🍅 百日刷题计划:第 17 / 100 天。

🍅 扫描主页左侧二维码,加入群聊,一起学习、一起进步 

🍅 欢迎点赞 👍 收藏 ⭐留言 📝 

金沙滩落日


算法是进阶架构师的基础,基础不牢,地动山摇,2021-8-14起开始刷题,目标100天,300道LeetCode算法题,分享是学习的最好方式,加油,嗨起来。 

1、LeetCode 448.找到所有数组中消失的数

题目

给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

小编思路

1、将数组进行排序

2、遍历数组,然后将不连续的数字添加到list中

小编菜解

/**
 * 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。
 * 请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
 *
 * 输入:nums = [4,3,2,7,8,2,3,1] -> [1,2,2,3,3,4,7,8]
 * 输出:[5,6]
 */
public static List<Integer> findDisappearedNumbers(int[] nums) {
    List<Integer> list = new ArrayList<>();
    if (nums.length == 0){
        return null;
    }
    Arrays.sort(nums);
    int n = nums.length;
    int left = 0;
    int step = 0;
    while (left < n){
        if(nums[left] == 1+step){
            left++;
        }else{
            if(nums[left] - (1+step) > 1){
                list.add(1+step+1);
            }
            step++;
        }
    }
    return list;
}

这道题没想太明白。。。

大佬指点江山

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        int n = nums.length;
        for (int num : nums) {
            int x = (num - 1) % n;
            nums[x] += n;
        }
        List<Integer> ret = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            if (nums[i] <= n) {
                ret.add(i + 1);
            }
        }
        return ret;
    }
}

2、LeetCode 453.最小操作次数使数组元素相等 TODO

题目

给定一个长度为 n 的 非空 整数数组,每次操作将会使 n - 1 个元素增加 1。找出让数组所有元素相等的最小操作次数。

小编思路

暴力算法,循环数组,除了最大的那个数,其它的都+1,直到最大数和最小数相等为止,不出意外会超出时间限制。

小编菜解

/**
 * 给定一个长度为 n 的 非空 整数数组,每次操作将会使 n - 1 个元素增加 1。找出让数组所有元素相等的最小操作次数。
 * [1,2,3]  =>  [2,3,3]  =>  [3,4,3]  =>  [4,4,4]
 */
public static int minMoves(int[] nums) {
    Arrays.sort(nums);
    int lg = nums.length;
    int step = 0;
    while (true){
        int min = nums[0];
        int max = nums[lg - 1];
        if (max == min){
            break;
        }
        for (int i = 0; i < lg - 1; i++) {
            nums[i] = nums[i] + 1;
        }
        step++;
        Arrays.sort(nums);
    }
    return step;
}

哈哈,果然如此,超出时间限制。

是不是arrays.sort消耗了过多的性能?改进一下

小编菜解进阶版

public static int minMoves(int[] nums) {
    int lg = nums.length;
    int step = 0;
    int max = 0;
    int min = 0;
    while (true){
        for (int i = 0; i < lg; i++) {
            if (nums[i] > max){
                max = nums[i];
            }
            if (nums[i] < min){
                min = nums[i];
            }
        }
        if (max == min){
            break;
        }
        for (int i = 0; i < lg - 1; i++) {
            nums[i] = nums[i] + 1;
        }
        step++;
    }
    return step;
}

依然超时。 

因为最大值与最小值之差,最小值想等于最大值,最小要进行max-min次+1,因此可以再次改进。

小编菜解终极版

public static int minMoves(int[] nums) {
    int step = 0;
    int min = 0;
    int max = nums.length - 1;
    while (true){
        for (int i = 0; i < nums.length; i++) {
            if (nums[max] < nums[i]){
                max = i;
            }
            if (nums[min] > nums[i]){
                min = i;
            }
        }
        int diff = nums[max] - nums[min];
        if (diff == 0){
            break;
        }
        step += diff;
        for (int i = 0; i < nums.length; i++) {
            if (i != max){
                nums[i] = nums[i] + diff;
            }
        }
    }
    return step;
}

依然超时,治标不治本,本身算法的问题。

大佬指点江山

public static int minMoves(int[] nums) {
    Arrays.sort(nums);
    int count = 0;
    for (int i = nums.length - 1; i > 0; i--) {
        count += nums[i] - nums[0];
    }
    return count;
}

 看了十分钟,硬是没看懂。先这样吧。

3、LeetCode 455.分发饼干

题目

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

小编思路

1、孩子一个数组,饼干一个数组,先按从大到小排序

2、倒序遍历饼干,倒序遍历孩子,饼干能满足孩子,则成功+1

3、当饼干遍历完毕,或者孩子遍历完毕,结束循环

小编菜解

public static int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);//孩子{1,2}
    Arrays.sort(s);//饼干{1,2,3}
    //可以分的饼干数量
    int sum = 0;
    int step = 0;
    //遍历饼干
    for (int i = s.length - 1; i >= 0; i--) {
        if ((g.length-step) > 0){
            //遍历孩子
            System.out.println("还剩孩子数:"+(g.length-1-step+1));
            for (int j = g.length-1-step; j >= 0 ; j--) {
                step++;
                //最大的饼干满足尾款最大的孩子时,完成+1
                System.out.println("饼干:"+s[i]);
                System.out.println("孩子胃口:"+g[j]);
                if(s[i] >= g[j]){
                    sum++;
                    System.out.println("分配饼干成功:"+sum);
                    break;
                }
            }
        }
    }
    return sum;
}

大佬指点江山

public int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);
    Arrays.sort(s);
    int numOfChildren = g.length, numOfCookies = s.length;
    int count = 0;
    for (int i = 0, j = 0; i < numOfChildren && j < numOfCookies; i++, j++) {
        while (j < numOfCookies && g[i] > s[j]) {
            j++;
        }
        if (j < numOfCookies) {
            count++;
        }
    }
    return count;
}

推荐阅读

【100天算法入门 - 每日三题 - Day16】第三大的数、字符串中的单词数、排列硬币

【100天算法入门 - 每日三题 - Day15】判断子序列、最长回文数、Fizz Buzz

【100天算法入门 - 每日三题 - Day14】两个数组的交集、有效的完全平方数、字符串中的第一个唯一字符

【100天算法入门 - 每日三题 - Day13】反转字符串、反转字符串中的元音字母、两个数组的交集

【100天算法入门 - 每日三题 - Day12】Nim游戏、3的幂、4的幂

【100天算法入门 - 每日三题 - Day11】丢失的数字、移动零、单词规律

【100天算法入门 - 每日三题 - Day10】二叉树的所有路径、各位相加、丑数 

【100天算法入门 - 每日三题 - Day9】汇总区间、2的幂、有效的字母异位词

【100天算法入门 - 每日三题 - Day8】同构字符串、存在重复元素、翻转二叉树

【100天算法入门 - 每日三题 - Day7】验证回文串、只出现一次的数字、多数元素

  • 75
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 63
    评论
评论 63
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值