2018链家笔试题

论坛 期权论坛 脚本     
匿名技术用户   2020-12-27 01:22   728   0

一、一个含有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的人分别在哪个组里。

示例:
输入
5
2 7 3 4 9
3
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();
 }

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP