算法刷题——7.2习题

简介: 算法刷题——7.2习题

文章目录


前言


为了结束假期的无效刷题,有幸参与了 高校算法学习社区的七月暑期刷题营,能和大佬们一起学习进步是一种幸福。不多说直接开始今天的算法习题之旅…


一、三个数的最大乘积


题目描述

给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。


解题思路

1.先排序根据情况找出最大乘积

首先将数组排序。

排序过后分为三种情况:


  • 如果数组中全是非负数,则排序后最大的三个数相乘即为最大乘积
  • 如果全是非正数,则最大的三个数相乘同样也为最大乘积
  • 如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,也可能是两个最小负数(即绝对值最大)与最大正数的乘积

综上,我们在给数组排序后,分别求出三个最大正数的乘积,以及两个最小负数与最大正数的乘积,二者之间的最大值即为所求答案。


2.直接找出我们需要的数值进行相乘比较(线性扫描)


通过思路一可以得出,无论怎么样我们所需要的无非就是五个数据:最大的三个数和最小的两个数,那么我们需要做的就是通过一次扫描找出这五个数保存下来,分别乘积比较。

代码:思路1

class Solution {
    public int maximumProduct(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] * nums[n - 1]);
    }
}


代码:思路2

class Solution {
    public int maximumProduct(int[] nums) {
        // 最小的和第二小的
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        // 最大的、第二大的和第三大的
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
        for (int x : nums) {
            //判断找出最小和第二小的
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }
            //判断找出最大二,第二大的,第三大的
            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }
        return (min1 * min2 * max1) > (max1 * max2 * max3) ? (min1 * min2 * max1) : (max1 * max2 * max3);
    }
}

二、有多少小于当前数字的数字

题目描述


给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。

换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。

以数组形式返回答案


来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/how-many-numbers-are-smaller-than-the-current-number


解题思路

1.嵌套两次遍历数组得出结果

首先创建一个相同长度的数组,通过两次遍历得出想要的结果

本思路就属于暴力破解了,自然时间复杂度相对较大


2.排序


排序应该是第二个自然想到的方法了吧将数组排序,并记录每一个数在原数组中的位置(不然最后的结果就不知道放在哪里了)。排序后的数组中的每一个数,我们找出其左侧第一个小于它的数,这样就能够知道数组中小于该数的数量


3.计数排序

这个思路就比较新奇了,小编也没有想到(可能见的比较少),一起来看看吧。感兴趣的小伙伴可以一起研究研究。这个的代码就不在写上了哦。


注意到数组元素的值域为[0,100],所以可以考虑建立一个频次数组 cntcnt ,cnt[i]cnt[i] 表示数字 ii 出现的次数。那么对于数字 ii 而言,小于它的数目就为 cnt[0…i-1]cnt[0…i−1] 的总和。


作者:LeetCode-Solution

链接:https://leetcode.cn/problems/how-many-numbers-are-smaller-than-the-current-number/solution/you-duo-shao-xiao-yu-dang-qian-shu-zi-de-shu-zi–2/

来源:力扣(LeetCode)


代码:思路一

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int[] res = new int[nums.length];
        for(int i = 0 ; i < nums.length; i++){
            int count = 0;
            for(int j = 0 ; j < nums.length ; j++){
                if(j == i ) continue;
                if(nums[j] != nums[i] && nums[j] < nums[i]) count++;
            }
            res[i] = count;
        } 
        return res;
    }
}

代码:思路二

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int n = nums.length;
        int[][] data = new int[n][2];
        for (int i = 0; i < n; i++) {
            data[i][0] = nums[i];
            data[i][1] = i;
        }
        Arrays.sort(data, new Comparator<int[]>() {
            public int compare(int[] data1, int[] data2) {
                return data1[0] - data2[0];
            }
        });
        int[] ret = new int[n];
        int prev = -1;
        for (int i = 0; i < n; i++) {
            if (prev == -1 || data[i][0] != data[i - 1][0]) {
                prev = i;
            }
            ret[data[i][1]] = prev;
        }
        return ret;
    }
}

总结


今天的算法题有些难度,有些题目只能想到暴力破解方法,自然这也是大多是小伙伴的思路,写完看看大佬们的更优解学习一下,这不也是很好的习惯吗。

😎重在坚持,继续努力。喜欢的小伙伴欢迎一键三连哦。😎


The man who fears losing has aleardy lost.

怕输的人已经输了。

-《权力的游戏》


相关文章
|
19天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
5月前
|
存储 算法 C语言
【数据结构与算法 刷题系列】合并两个有序链表
【数据结构与算法 刷题系列】合并两个有序链表
|
5月前
|
算法
数据结构和算法学习记录——习题-移除链表元素
数据结构和算法学习记录——习题-移除链表元素
24 0
|
1月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
13 0
|
3月前
【刷题记录】最大公因数,最小公倍数(辗转相除法、欧几里得算法)
【刷题记录】最大公因数,最小公倍数(辗转相除法、欧几里得算法)
|
3月前
|
算法 Python
【Leetcode刷题Python】改进的算法,高效求一个数的因子
一个高效的Python函数用于找出一个整数的所有因子,通过仅遍历到该数平方根的范围来优化性能。
38 0
|
5月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
5月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
42 2
|
5月前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
77 1