一起学算法(枚举篇)

news2025/2/24 15:07:55

概念

枚举:就是把满足题目条件的所有情况都列举出来,然后一一判断寻找最优解的过程

1.最值问题

1.两个数的最值问题

两个数的最小值,利用Java的运算符就可以实现

int Min(int a,int b){
   return a<b?a:b;
}

2.n个数的最值问题

当有n个数时Ai时,我们可以首先取前两个数,计算最小值;然后再拿这个最小值和第三个数去比较,得到的最小值再去和第四个数进行比较,一次类推,就可以计算出n个数中最小的值

假设前i个数的最小值为min,则有递推公式如下:

所以将这个递推公式翻译成java代码是这样的:

   public int min(int a,int b){
       return a<b?a:b;
   }
   public int findMin(int[] num){
       int min=num[0];
       for(int i=1;i<num.length;i++){
           min=min(min,num[i]);
       }
       return min;
   }

 3.最值问题的下标

有些时候我们求的并不是一个最小的数,而是要求出这个数组中最小数的下标,那么可以直接记录下标,并且比较的时候直接通过下标去索引到值,然后再进行比较,像这样:

   public int findMin(int[] num){
       int minIndex=0;
       for(int i=1;i<num.length;i++){
           if(num[i]<num[minIndex]){
               minIndex=i;
           }
       }
       return minIndex;
   }

2.最值问题的进阶

1.第三大的数

       有时候,我们求最大的数不够,想要求次大的,或者是第三大的数,我们应该怎么做呢?这样的问题,核心思路就是先把最大的求出来,然后忽略最大数的情况下,再去求最大的,这时候就得到次大的了,再把次大的忽略掉,再次求最大的,就是第三大值了

2.数组中两元素的最大乘积

       要求找到数组中两个元素的最大乘积,数组元素一定是正数,那么我们知道最大的元素相乘一定是最大的,所以就是找到最大值和次大值,但是这个问题和第三大的数稍微有点区别,相同的数会被计算进去,所以我们找到最大值以后,可以将它的下标忽略掉,然后再去找最大的值,这样找到的一定是两个可重复的最大元素和次大元素,将两者相乘即可。

3.降维思想

一些统计类问题,第一个思路就是枚举所有的情况,然后再次考虑是不是能够某些O(n)降为O(1),这就是降维思想,具体看

统计上升四元组的数目

1.O(n^4):

最坏的时间复杂度就是枚举i、j、k、l四个变量,然后判定nums四个数的关系,进行统计累加,但是这种做法在范围很大的时候势必超时

2.O(n^2)

  1. 首先,我们枚举j和k,然后对所有满足nums[i]>nums[j]的下标对,执行下一步
  2. 那么只要我们找到数组下标为0~j-1的数中,小于nums[k]的个数,记作a(也就是所有满足条件的i);找到数组下标为k+1~n-1的数中,大于nums[j]的个数,记作b(也就是所有满足条件的);将a*b就是所有满足条件的(i,l)对,把所有的(i,l)累加,就是我们要求出的答案
  3. 问题就转换为找到数组下标0~i-1的数中,小于nums[k]的个数和找到数组下标为k+1~n-1的数中,大于nums[i]的个数

Leetcode题单:

K个元素的最大和

class Solution {
    public int maximizeSum(int[] nums, int k) {
       if(nums==null||nums.length==0){
           return 0;
       }
       int ans=0;
       //执行k次循环
       while(k!=0){
         //保存最大值的下标
         int maxIndex=0;
         for(int i=0;i<nums.length;i++){
             if(nums[i]>nums[maxIndex]){
                 maxIndex=i;        
                      }
         }
          ans+=nums[maxIndex];
        nums[maxIndex]+=1;
         k--;
       }
       return ans;
    }
}

第三大的数

class Solution {
    public int thirdMax(int[] nums) {
if(nums==null||nums.length==0){
          return -1;
      }
      int[] s=Arrays.stream(nums).distinct().sorted().toArray();
      if(s.length<3){
          return s[s.length-1];
      }
      return s[s.length-3];
    }
}

统计上升四元组

class Solution {
    public long countQuadruplets(int[] nums) {
        // 初始化四元组的数量
        long quadruplets = 0;
        // 数组的长度
        int n = nums.length;
        // 记录每个数字的后面比它小的数字的个数
        int[][] lessCount = new int[n][n + 1];
        // 记录每个数字的前面比它大的数字的个数
        int[][] greaterCount = new int[n][n + 1];

        // 计算lessCount数组
        getLess(nums, n, lessCount);
        // 计算greaterCount数组
        getGreater(nums, n, greaterCount);

        // 遍历数组,计算满足条件的四元组数量
        for (int j = 1; j < n - 2; ++j) {
            for (int k = j + 1; k < n - 1; ++k) {
                if (nums[k] < nums[j]) {
                    // 更新四元组数目
                    quadruplets += (long) (lessCount[j - 1][nums[k]] * greaterCount[k + 1][nums[j]]);
                }
            }
        }

        // 返回结果
        return quadruplets;
    }

    // 计算lessCount数组
    void getLess(int[] nums, int n, int[][] lessCount) {
        // 遍历数组,计算每个数字的后面比它小的数字的个数
        for (int i = 0; i < n; ++i) {
            if (i != 0) {
                // 复制上一行的数组值
                lessCount[i] = Arrays.copyOf(lessCount[i - 1], n + 1);
            }

            // 统计后面比当前数字小的数字的个数
            for (int j = nums[i]; j < n; ++j) {
                ++lessCount[i][j];
            }
        }
    }

    // 计算greaterCount数组
    void getGreater(int[] nums, int n, int[][] greaterCount) {
        // 遍历数组,计算每个数字的前面比它大的数字的个数
        for (int i = n - 1; i >= 0; --i) {
            if (i != n - 1) {
                // 复制下一行的数组值
                greaterCount[i] = Arrays.copyOf(greaterCount[i + 1], n + 1);
            }

            // 统计前面比当前数字大的数字的个数
            for (int j = 1; j < nums[i]; ++j) {
                ++greaterCount[i][j];
            }
        }
    }
}
/*
在给定的Java代码中,我们使用两个二维数组 lessCount 和 greaterCount 分别记录每个数字的后面比它小的数字的个数和前面比它大的数字的个数。

在 getLess 方法中,我们遍历数组 nums,对于每个数字 nums[i],我们复制上一行的数组值到当前行(即 lessCount[i] = Arrays.copyOf(lessCount[i - 1], n + 1))。然后,我们统计后面比当前数字小的数字的个数,即从 nums[i]  到 n-1,并将对应位置的计数器加1(++lessCount[i][j])。

在 getGreater 方法中,我们逆向遍历数组 nums,对于每个数字 nums[i],我们复制下一行的数组值到当前行(即 greaterCount[i] = Arrays.copyOf(greaterCount[i + 1], n + 1))。然后,我们统计前面比当前数字大的数字的个数,即从 1 到 nums[i] - 1,并将对应位置的计数器加1(++greaterCount[i][j])。

接下来,在 countQuadruplets 方法中,我们遍历 nums 数组的中间两个数字,即 j 和 k。我们检查 nums[k] 是否小于 nums[j],如果是,意味着满足题目要求的四元组 (nums[i], nums[j], nums[k], nums[l])。此时,我们可以利用之前计算的 lessCount 和 greaterCount 数组来获取符合条件的数量,即 lessCount[j - 1][nums[k]] 表示在 nums[j - 1] 之前比 nums[k] 小的数字的个数,而 greaterCount[k + 1][nums[j]] 表示在 nums[k + 1] 之后比 nums[j] 大的数字的个数。我们将这两个值相乘,并将其加到 quadruplets 中。

最后,我们返回 quadruplets,即满足题目要求的四元组的总数。
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/812753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

禁用右键菜单AMD Software: Adrenalin Edition

本文参考链接&#xff1a; 删除win11右键一级菜单的AMD驱动栏 - 哔哩哔哩 windows11 求助删除右键菜单方法_windows11吧_百度贴吧 Windows安装最新的AMD显卡驱动后&#xff0c;右键菜单会多出AMD Software: Adrenalin Edition。使用一些右键菜单管理工具也没能屏蔽禁用掉该功…

机器学习---线性回归、多元线性回归、代价函数

1. 线性回归 回归属于有监督学习中的一种方法。该方法的核心思想是从连续型统计数据中得到数学模型&#xff0c;然后 将该数学模型用于预测或者分类。该方法处理的数据可以是多维的。 回归是由达尔文的表兄弟Francis Galton发明的。Galton于1877年完成了第一次回归预测&…

数据分析基础-Excel图表的美化操作(按照教程一步步操作)

一、原始数据 包含月份和对应的销量和产量。 时间销量产量1月60722月38673月28344月58685月67596月72357月61428月24319月556710月243511月122112月2645 二、原始的图表设计-采用Excel自带模板 三、优化思路 1、删除多余元素 2、弱化次要元素 对于可以弱化的元素&#xff0c…

NASM汇编

1. 前置知识 1. 汇编语言两种风格 intel&#xff1a;我们学的NASM就属于Intel风格AT&T&#xff1a;GCC后端工具默认使用这种风格&#xff0c;当然我们也可以加选项改成intel风格 2. 代码 1. 段分布 .text: 存放的是二进制机器码&#xff0c;只读.data: 存放有初始化的…

弯道超车必做好题锦集一(C语言选择题)

前言&#xff1a; 编程想要学的好&#xff0c;刷题少不了&#xff0c;我们不仅要多刷题&#xff0c;还要刷好题&#xff01;为此我开启了一个弯道超车必做好题锦集的系列&#xff0c;每篇大约10题左右。此为第一篇选择题篇&#xff0c;该系列会不定期更新&#xff0c;后续还会…

《EalsticSearch从入门到实战》-CRUD+JAVA常用操作

目录 《EalsticSearch从入门到实战》 windows环境安装elasticsearchkibana并完成JAVA客户端查询《EalsticSearch从入门到实战》-CRUDJAVA常用操作 前言 上一篇《windows环境安装elasticsearchkibana并完成JAVA客户端查询》中我们已经完成了EalsticSearchKibana环境的安装&a…

页面生成图片或PDF node-egg

没有特别的幸运&#xff0c;那么就特别的努力&#xff01;&#xff01;&#xff01; 中间件&#xff1a;页面生成图片 node-egg 涉及到技术node egg Puppeteer 解决文书智能生成多样化先看效果环境准备初始化项目 目录结构核心代码 完整代码https://gitee.com/hammer1010_ad…

web自动化测试,定位不到元素的原因及解决方案

1.动态id定位不到元素 分析原因&#xff1a;每次打开页面&#xff0c;ID都会变化。用ID去找元素&#xff0c;每次刷新页面ID都会发生变化。 解决方案&#xff1a;推荐使用xpath的相对路径方法或者cssSelector查找到该元素。        2.iframe原因定位不到元素 分析原因…

SQL注入之布尔盲注

SQL注入之布尔盲注 一、布尔盲注介绍二、布尔盲注的特性三、布尔盲注流程3.1、确定注入点3.2、判断数据库的版本3.3、判断数据库的长度3.4、猜解当前数据库名称&#xff08;本步骤需要重复&#xff09;3.5、猜解数据表的数量3.6、猜解第一个数据表名称的长度3.7、猜解第一个数据…

【React】关于组件之间的通讯

&#x1f31f;组件化&#xff1a;把一个项目拆成一个一个的组件&#xff0c;为了便与开发与维护 组件之间互相独立且封闭&#xff0c;一般而言&#xff0c;每个组件只能使用自己的数据&#xff08;组件状态私有&#xff09;。 如果组件之间相互传参怎么办&#xff1f; 那么就要…

Python 算法交易实验65 算法交易二三事

说明 对算法交易的一些内容做一些回顾和反思吧。 老规矩&#xff0c;先chat一下 道理说的都对&#xff0c;如果要补充就推荐再看一本书量化交易:如何建立自己的算法交易事业,我觉得这样就比较完整了。 简单来说&#xff0c;把量化当成事业&#xff0c;而不是一种投机&#…

一起学算法(计算排序篇)

概念&#xff1a; 计数排序&#xff08;Counting sort&#xff09;是一个非基于比较稳定的线性时间的排序算法 非基于比较&#xff1a;之前学的排序都是通过比较数据的大小来实现有序的&#xff0c;比如希尔排序等&#xff0c;而计数排序不需要比较数据的大小而进行排序&…

数据结构:谈快速排序的多种优化和非递归展开,以及排序思想归纳

文章目录 写在前面快速排序的基本体系快速排序的优化快速排序的非递归实现排序分类总结插入排序选择排序交换排序归并排序 写在前面 快速排序作为效率相当高的排序算法&#xff0c;除了对于特殊数据有其一定的局限性&#xff0c;在大多数应用场景中都有它特有的优势和应用&…

PHP8的数据类型转换-PHP8知识详解

什么是数据类型转换&#xff1f; 答&#xff1a;数据从一个类型转换成另外一个类型&#xff0c;就是数据类型转换。 在PHP8中&#xff0c;变量的类型就是由赋值决定的&#xff0c;也就是说&#xff0c;如果 string 赋值给 $var&#xff0c;然后 $var 的类型就是 string。之后…

Python:给MySQL创建1000张表和创建1张有50个字段的表

1、创建1000张表 import pymysqldbhost "10.1.1.143" dbuser "root" dbpassword "123456" dbname "demo_cg1000" dbport 3306 dbconn pymysql.connect(hostdbhost, userdbuser, passworddbpassword, dbdbname, portdbport)mycu…

前端学习--vue2--2--vue指令基础

写在前面&#xff1a; 前置内容 - vue配置 文章目录 插值表达式v-html条件渲染v-show和v-ifv-ifv-if的扩展标签复用组件 v-show v-on /事件v-bind /&#xff1a;属性v-modelv-for 循环元素v-slotv-prev-cloak vue指令只的是带有v-前缀的特殊标签属性 插值表达式 插值表达式{…

【MATLAB第62期】基于MATLAB的PSO-NN、BBO-NN、前馈神经网络NN回归预测对比

【MATLAB第62期】基于MATLAB的PSO-NN、BBO-NN、前馈神经网络NN回归预测对比 一、数据设置 1、7输入1输出 2、103行样本 3、80个训练样本&#xff0c;23个测试样本 二、效果展示 NN训练集数据的R2为&#xff1a;0.73013 NN测试集数据的R2为&#xff1a;0.23848 NN训练集数据的…

【机器学习】Feature Engineering and Polynomial Regression

Feature Engineering and Polynomial Regression 1. 多项式特征2. 选择特征3. 缩放特征4. 复杂函数附录 首先&#xff0c;导入所需的库&#xff1a; import numpy as np import matplotlib.pyplot as plt from lab_utils_multi import zscore_normalize_features, run_gradien…

qt添加图标

1.添加资源 选择QtWidgetsApp.qrc文件打开 添加图标文件路径 添加图标文件 2.按钮添加图标 图标路径为:/res/res/swicth.jpg &#xff08;1&#xff09;代码设置图标 ui.pushButton_OPen->setIcon(QIcon(":/res/res/swicth.jpg")); &#xff08;2&#xff09;属…

设计模式:生成器模式

这个模式书上讲的比较简单&#xff0c;但是感觉精华应该是讲到了。 引用下其它博客的总结&#xff1a;生成器模式的核心在于分离构建算法和具体的构造实现&#xff0c;从而使得构建算法可以重用。 【设计模式】建造者模式_鼠晓的博客-CSDN博客