AcWing 1239. 乘积最大 双指针 分类讨论

该代码片段展示了一个Java程序,用于解决给定数组中选择k个数使乘积最大的问题。采用分情况讨论和双指针策略,处理奇数个负数的情况,以及按乘积大小选取数对。程序首先对数组进行排序,然后根据k的奇偶性决定如何选取元素以最大化乘积。
摘要由CSDN通过智能技术生成

乘积最大
在这里插入图片描述
输入样例1

5 3
-100000
-10000
2
100000
10000

输出样例1

999100009

输入样例2

5 3
-100000
-100000
-2
-100000
-100000

输出样例2

-999999829

⭐思路:分情况讨论 + 双指针

🐷 k == n
🥚 没得选

🐷 k < n
 🥚 k 为奇数
  ① 有正数,取一个最大的正数,其他按 乘积大小的取数对
  ② 无正数,按乘积最小取
 🥚 k 为偶数
  ① 依次取乘积大的数对

🤠 大佬点睛

在这里插入图片描述
👨‍🏫 友情提示:需要比较的数不能取模,不然会影响比较的结果(细节取模)
😋 只要预先处理了一个数,奇数个 就 转变成 偶数个 的问题啦

import java.util.*;

public class Main
{
	static int N = 100010;
	static int mod = 1000000009;

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int k = sc.nextInt();

		int[] a = new int[n];

		for (int i = 0; i < n; i++)
		{
			a[i] = sc.nextInt();
		}

		int l = 0;
		int r = n - 1;
		long res = 1;
		int sign = 1;// 记录结果的正负
		Arrays.sort(a);// 默认升序

		if (k % 2 == 1)//预先处理 k 为 奇数 的情况
		{
			res = a[r--];// 取出最大的数(有可能是负数)
			k--;
			if (res < 0)
				sign = -1;// 最大值是负数,所有数都是负数,而且是奇数个,所以结果也是负数
		}
		while (k != 0)
		{
//			两边都是成对成对的取,因为 while 里边 k 肯定是 偶数
			long x = (long) a[l] * a[l + 1];
			long y = (long) a[r] * a[r - 1] ;
			//要比较,所以不能预先取模了
			if (x * sign > y * sign)
			{
				res = x % mod * res % mod;// == (x*res)%mod 分开取模可以保证相乘的过程爆 long
				l += 2;
				k -= 2;
			} else
			{
				res = y % mod * res % mod;
				r -= 2;
				k -= 2;
			}
		}

		System.out.println(res);

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值