两个已排序的List<Integer>求其交集

本文介绍了一种优化方法,通过遍历较小的已排序整型列表,利用其排序特性,快速找到与另一个列表的交集,减少额外空间使用并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两个已排序的List<Integer>求其交集

    近日参加的一个游戏公司的笔试,其中的一个题如下:给定两个已排序的整型列表List<Integer> List0与List1,求出其交集,要求速度最快,额外占用空间最少的算法?

   当时的想法没怎么完善,想到用Map,或Hashtable,但是实现起来不知道如何做,于是只写了双重for循环来实现,最后面试官好像不太满意,提醒我说“已排序”。仔细想过之后,用Set实现会比较好。具体实现如下。这样应该达到要求了吧。发现游戏公司的要求挺高,不过很向往的。加油!

  

package day01;

import java.util.*;

public class ListCross {


	/**
	 * @author zhaohuafei
	 * @param args
	 */
	public static void main(String[] args) {
		ListCross ls = new ListCross();
		List<Integer> list0 = new ArrayList<Integer>();
		list0.add(1);
		list0.add(2);
		list0.add(3);
		list0.add(4);
		list0.add(5);
		list0.add(6);
		List<Integer> list1 = new ArrayList<Integer>();
		list1.add(3);
		list1.add(4);
		list1.add(5);
		list1.add(6);
	List<Integer> list =	ls.getListCross(list0 , list1);
		System.out.println(list);//[3, 4, 5, 6]
	}

	public List<Integer> getListCross(List<Integer> list0, List<Integer> list1) {
		/**
		 * 先遍历size小的list每个元素(这个list设为la,另一个为lb),
		 * 遍历时与另个list中元素比较,
		 * 找到相同的元素,因为是排序的,假设为升序。
		 * la中每下一个元素都不必与lb的第一个开始比较,
		 * 而是接着上个元素比较完之后的剩余元素直至相同
		 */
		 
		List<Integer> la = list0;
		List<Integer> lb = list1;
		List<Integer> lc = new ArrayList<Integer>();
		int a = list0.size();
		int b = list1.size();
		int bs = b;// size of the longer list
		if (a > b) {
			la = list1;
			lb = list0;
			bs = a;
		}
		int c = 0;// 与lb中哪个元素开始比较

		for (Integer i : la) {
			for (int k = c; k < bs; k++) {
				if (lb.get(k) > i)
					break;// lb.get(k)大于i 则lb的下一个元素也只会比i大所以
				// 就不用再执行了
				if (lb.get(k) == i)// cross
				{
					c = k + 1; // 这个地方比较重要,lb中下次就c以前的就不用比较 了
					lc.add(i);
					break;
				}// if
			}// for
		}// for
		return lc;
	}

}


    



根据快乐8选十规则(从 1 1到 80 80中随机选择 10 10个不重复数字),结合双色球生成逻辑和引用中的实现经验13,以下是程序实现方法及验证逻辑: 程序实现核心逻辑 号码生成: 每次生成 10 10个不重复数字,范围 [ 1 , 80 ] [1,80] 两注号码需独立生成,避免重复种子干扰 数学验证:组合数应为 � 80 10 ≈ 1.646 × 10 12 C 80 10 ​ ≈1.646×10 12 种可能性 Python实现 Python import random def generate_happy8(): numbers = sorted(random.sample(range(1, 81), 10)) return f"选十号码:{numbers}" # 生成两注 print("第1注:" + generate_happy8()) print("第2注:" + generate_happy8()) Java实现 Java import java.util.*; public class Happy8 { public static void main(String[] args) { System.out.println("第1注:" + generate()); System.out.println("第2注:" + generate()); } public static String generate() { List<Integer> numbers = new ArrayList<>(); for (int i = 1; i <= 80; i++) numbers.add(i); Collections.shuffle(numbers); List<Integer> selected = new ArrayList<>(numbers.subList(0, 10)); Collections.sort(selected); return "选十号码:" + selected; } } JavaScript实现 JavaScript function generateHappy8() { const numbers = new Set(); while (numbers.size < 10) { numbers.add(Math.floor(Math.random() * 80) + 1); } return `选十号码:[${[...numbers].sort((a,b) => a - b)}]`; } // 生成两注 console.log("第1注:" + generateHappy8()); console.log("第2注:" + generateHappy8()); 关键验证点 数量验证:每注必须严格包含 10 10个数字 范围验证:所有数字在 [ 1 , 80 ] [1,80]区间内 唯一性验证:无重复数字(数学验证: � 80 10 C 80 10 ​ 组合数) 独立性验证:两注之间无数字关联14 翻译
06-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值