2018链家笔试题

一、一个含有n个元素的数组,找出m个数使其和为K

 参考:打印和为sum的组合,动规法+DFS+迭代法https://blog.csdn.net/qq_19446965/article/details/81775702

动态规划:只能找出一组,O(n^2)

找出所有参考上述;链接


// 打印和为n的组合,动规法,O(n^2)
	public static List<Integer> findSums(int[] a, int n) {
		boolean[] dp = new boolean[n + 1];
		List<Integer>[] list = new ArrayList[101];
		for (int i = 0; i < list.length; i++) {
			list[i] = new ArrayList<>();
		}
		dp[a[0]] = true;
		list[a[0]].add(a[0]);
		for (int i = 1; i < a.length; i++) {
			for (int j = n; j >= a[i]; j--) {
				if (dp[j - a[i]]) {
					dp[j] = true;
					list[j].addAll(list[j - a[i]]);
					list[j].add(a[i]);
				}
			}
			if (dp[n]) {
				break;
			}
		}
		return list[n];
	}

二、数据分组

题目描述

小组编号问题。输入一组数【2,7,3,4,9】,表示第一组有2个人,编号为【1、2】,第二组有7个人编号为【3~9】,第三组有3个人编号为【10~12】,第四组有4个人编号为【13~16】,第五组有9个人编号为【17~25】。

现在求,编号为1、25、11的人分别在哪个组里。

示例: 
输入 

2 7 3 4 9 

1 25 11

输出 
1 5 3

计算累加小组成员数,结合二分查找,复杂度O( min(n, mlogn) )

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int n = sc.nextInt();
			int[] arr = new int[n];
			arr[0] = sc.nextInt();
			for (int i = 1; i < n; i++) {
				arr[i] = arr[i - 1] + sc.nextInt();
			}
			int m = sc.nextInt();
			int query = 0;
			int index = 0;
			for (int i = 0; i < m; i++) {
				query = sc.nextInt();
				index = search(arr, query);
				System.out.print(index + " ");
			}

		}
		sc.close();
	}

	public static int search(int a[], int target) {
		int left = 0;
		int right = a.length - 1;
		int mid = 0;
		while (left < right) {
			mid = left + (right - left) / 2;
			if (target >= a[mid]) {
				left = ++mid;
			} else {
				right = mid;
			}
		}
		return left + 1;
	}

三、3个有序数组查找第k个

1. 在每一个数组中取出第一个值,然后把它们放在一个大小为3的小根堆中。此步骤的时间复杂度为O(3)

2. 取出堆中的最小值, 然后把该最小值所处的数组的下一个值放在数组的第一个位置。此步骤的时间复杂度为O(lg 3).

3. 不断的重复步骤二,直到去出k个或所有的数组都为空。

建堆只建一次,复杂度为O(3);所以为O(3)+O(k*lg 3) = O(k)

	public static int findKth(int[] a, int b[], int c[], int count) {
		PriorityQueue<Integer> s = new PriorityQueue<>();
		int i = 0, j = 0, k = 0;
		s.add(a[i]);
		s.add(b[j]);
		s.add(c[k]);
		while (count > 1) {
			if (s.peek() == a[i]) {
				s.poll();
				if (i + 1 < a.length) {
					s.add(a[++i]);
				}
				count--;
				continue;
			}
			if (s.peek() == b[j]) {
				s.poll();
				if (j + 1 < b.length) {
					s.add(b[++j]);
				}
				count--;
				continue;
			}
			if (s.peek() == c[k]) {
				s.poll();
				if (k + 1 < c.length) {
					s.add(c[++k]);
				}
				count--;
				continue;
			}

		}
		return s.peek();
	}

猜你喜欢

转载自blog.csdn.net/qq_19446965/article/details/81782773