贪心策略:不断循环操作数组arr中的任意两个数,当只剩下1个数,返回这个数可能的最大值

贪心策略:不断循环操作数组arr中的任意两个数,当只剩下1个数,返回这个数可能的最大值

阿里笔试原题
提示:从本文开始,咱们来说贪心策略系列文章!!

贪心策略在互联网大厂的招聘笔试和面试中的地位!!!在笔试中考贪心,而面试不考贪心。

(1)贪心在笔试中:75%的考题都是贪心策略,为啥呢,一方面考你的聪明程度,另一方面,考你的代码编写能力;所以我参加过的笔试证明了这一点,往往大厂给你三个算法题,第1道题一定是贪心,排序结合的算法题,你需要懂点脑子,了解一下排序和堆啥的数据结构,还得会点贪心技巧,才能设计出来;
(2)面试不怎么考贪心策略,为什么?因为面试考你的是算法的优化能力,所以如果给你贪心的话,你一下子想到了解决方案,也不谈什么优化的事情,没意义,所以不考贪心。
(3)你必须要认识到:最简单的是国内的面试过程(嘴说的事情,都好办),难度中上等的是国外的笔试面试,最难的国内的算法笔试。 那么,你一定要明白,最难的还是国内的算法笔试题!!!因此要多练,多学,多见题,多思考,多总结,才能拿下。

以下是贪心策略基础题目系列文章:
(1)贪心策略:请你计算i×arr[i]的累加和最大值
(2)贪心策略:请你设计最优的安排会议日程表,以使得举行的会议数最多
(3)贪心策略:求一条街上最少应该放多少盏灯,才能照亮整条街的商户
(4)贪心策略:请你将字符串拼接,最终拼接好的字符串字典序最小
(5)贪心策略:请你最最小的金条分割代价


题目

本题,和上面的(5),一模一样,本题是阿里的笔试原题
(5)贪心策略:请你最最小的金条分割代价

输入2行,第一行n,代表n个数字,
第二行,就是你要输入的n个数字arr[i],现在对数组进行2种操作:

1)如果有俩相同的数,将其求和,然后sum放入arr;
2)如果俩数不相同,则取两者最大值max,放入arr;
不断循环操作,直到arr中只剩下1个数,返回这个数可能的最大值是多少?


一、审题

示例:
4
4 2 5 4
4和4相同,将其求和,8
放入arr=2 5 8
25不同,求max,5放入arr
arr=5 8
求max,arr=8
8就是结果


二、贪心策略,就是类似哈夫曼树,用小根堆解决

咱们要最后的最大值,那就要从最小值开始操作。

考场上的情况:我1分钟手撕完成,
(1)把arr全部放入小根堆,按照题目中的操作1)2)弹出堆顶的2个,求得cur,
(2)然后cur放入小根堆,循环玩弹出;
当小根堆只剩下1个数,返回它;

比如:
arr = 4 2 5 4
在这里插入图片描述
为什么当时我就想到了这个贪心策略呢?
很简单,在此之前,我见过类似的题目,人还没有说得这么明显呢
(5)贪心策略:请你最最小的金条分割代价

因此见过黄金分割代价最小这个题,就知道哈夫曼树,就是这么操作的。取俩数,然后操作,得到一个结果cur放入堆中,再继续玩
思路前所未有相似:

手撕代码:
这里要注意,真正的大厂笔试题,是输入格式也要你控制的
因为出题的人都是ACM竞赛和极限编程的大佬们,ACM打比赛的题目就是这种输入的格式

Scanner in = new Scanner(System.in);//这是大厂们的输入格式

然后后面不挂你输入字符串,还是字符数组,还是数字数组,都可以这么去读取:

int N = in.nextInt();//输入第一行
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = in.nextInt();//第二行是一个数组
        }
        //有时候可能是一个字符串
        //String s = in.nextLine();//一行读取

本题的代码是:

//阿里巴巴原题:
    //输入2行,第一行n,代表n个数字,
    //第二行,就是你要输入的n个数字arr[i],现在对数组进行2种操作:
    //
    //1)如果有俩相同的数,将其求和,然后sum放入arr;
    //2)如果俩数不相同,则取两者最大值max,放入arr;
    //不断循环操作,直到arr中只剩下1个数,返回这个数可能的最大值是多少?

    public static void maxValue(){
        Scanner in = new Scanner(System.in);//这是大厂们的输入格式
        int N = in.nextInt();//输入第一行
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = in.nextInt();//第二行是一个数组
        }
        //有时候可能是一个字符串
        //String s = in.nextLine();//一行读取

        PriorityQueue<Integer> heap = new PriorityQueue<>();
        for (int i = 0; i < N; i++) {
            heap.add(arr[i]);
        }

        //对比
        while (heap.size() != 1){
            int a = heap.poll();
            int b = heap.poll();

            heap.add(a == b ? a + b : Math.max(a, b));
        }

        System.out.println(heap.peek());
    }

    public static void main(String[] args) {
        maxValue();
    }

测试:

4
4 2 5 4
8

明白了见过贪心的题目之后,今后遇到大厂的题目,是不是就可以尽快有思路了。


总结

提示:重要经验:

1)从本题可以实实在在论证:贪心的题目就是多见题,多思考,多总结,培养敏感度!
2)本题题目说得很直白,要最大值,操作时,取俩数,然后不断对比,再次放入arr,这个过程就可以用哈夫曼树解决,小根堆模拟。
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以通过以下步骤来找出包含10个元素一维数组最大值和最小值,并交换这个数的位置: 1. 声明一个长度为10的一维数组,存储10个元素。 2. 初始化数组的元素,可以手动输入或使用随机生成。 3. 定义变量max和min,分别表示最大值和最小值,初始值为数组的第一个元素。 4. 使用for循环遍历数组的所有元素,比较每个元素与max和min的大小关系,更新max和min的值。 5. 找到最大值和最小值之后,交换它们在数组的位置。可以使用一个间变量来完成交换操作。 以下是示例代码: ```python # 声明一个长度为10的一维数组 arr = [0] * 10 # 初始化数组的元素,这里使用随机生成 import random for i in range(10): arr[i] = random.randint(1, 100) # 找出最大值和最小值,并记录它们的下标 max_idx = min_idx = 0 for i in range(1, 10): if arr[i] > arr[max_idx]: max_idx = i elif arr[i] < arr[min_idx]: min_idx = i # 输出最大值和最小值 print("最大值为:", arr[max_idx]) print("最小值为:", arr[min_idx]) # 交换最大值和最小值的位置 temp = arr[max_idx] arr[max_idx] = arr[min_idx] arr[min_idx] = temp # 输出交换后的数组 print("交换后的数组为:", arr) ``` 注意,以上代码是Python语言的示例代码,如果您使用的是其他编程语言,代码会有所不同,但是思路是相通的。 ### 回答2: 对于含有10个元素的一维数组,我们可以使用循环遍历的方式找出最大值和最小值。首先,我们可以设定一个初始值,假设一维数组的第一个元素为最大值,第一个元素也为最小值。然后,我们可以遍历整个一维数组,使用if语句判断是否找到了更大的元素或更小的元素,如果是,则更新最大值和最小值的值和下标。代码如下: int a[10]={1,2,3,4,5,6,7,8,9,10}; int max_val=a[0]; int min_val=a[0]; int max_index=0; int min_index=0; for(int i=1;i<10;i++){ if(a[i]>max_val){ max_val=a[i]; max_index=i; } if(a[i]<min_val){ min_val=a[i]; min_index=i; } } 一旦找到最大值和最小值的位置,我们可以通过交换个数的位置来实现互换操作,代码如下: int temp=a[max_index]; a[max_index]=a[min_index]; a[min_index]=temp; 完成以上操作后,一维数组最大值和最小值的位置已经被互换了。 ### 回答3: 首先,我们需要理解一维数组的概念。一维数组是由若干个元素组成的有序集合,这些元素通过一个索引来访问和操作。在本题,我们需要找出10个元素一维数组最大值和最小值,并将它们的位置互换。 要实现这个目标,我们可以采用遍历数组的方法。首先,我们可以设定一个变量max,把数组一个元素赋值给它,然后依次访问数组的每个元素,与max比较大小,如果该元素大于max,则把它赋值给max。同理,设定一个变量min,把数组一个元素赋值给它,然后依次访问数组的每个元素,与min比较大小,如果该元素小于min,则把它赋值给min。经过这个过程,我们就可以找出数组最大值和最小值了。 接下来,我们将最大值和最小值的位置互换。我们可以采用交换元素的方法,具体步骤如下: 1. 定义一个变量temp,把最大值赋给它。 2. 把最小值赋给最大值的位置。 3. 把temp赋给最小值的位置。 经过这个过程,最大值和最小值的位置就互换了。 在实际编程,我们可以采用如下代码实现: ``` int arr[10]={1,5,8,2,6,4,9,3,7,10}; int max=arr[0]; int min=arr[0]; int temp; for(int i=1;i<10;i++){ if(arr[i]>max){ max=arr[i]; } if(arr[i]<min){ min=arr[i]; } } temp=max; arr[max]=min; arr[min]=temp; ``` 以上代码实现了找出一个包含10个元素的一维数组最大值和最小值,并互换这个数的位置的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰露可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值