搜狗2014年笔试题-两递增数组A和B,求A[i]+B[j]中前k个最小值(Java)

来源:互联网 发布:淘宝店铺手机登陆 编辑:程序博客网 时间:2024/05/17 08:53
package array;import java.util.PriorityQueue;import java.util.Queue;import sort.Sort;/** * 已知两递增数组A={ai}和B={bj},对于A[i]+B[j],输出前k个最小值 * */public class MinTwoArrayK {/** * 算法复杂度(o(n^2)) * 1、先将所有可能的值求出来 * 2、排序 * @param a 递增数组 * @param b 递增数组 * @param k 前k个最小值 */public static void sortMethod(int a[], int b[], int k) {int c[] = new int[a.length * b.length];for (int i = 0; i < a.length; i++) {for (int j = 0; j < b.length; j++) {c[i * a.length + j] = a[i] + b[j];}}Sort.buddleSort(c);for (int i = 0; i < k; i++) {System.out.print(c[i] + " ");}}/** * 算法复杂度k(log(k)) * 1、根据当前节点的状态,获取下一个可能的状态 * 2、一般的算法:如果当前a[i]+b[j]最小,下一个最小的状态可能是a[i+1]+b[j]或者a[i]+b[j+1]。如果这样的话就会产生重复,比如a[i+1]+b[j]下一个状态是 * a[i+1]+b[j+1]和a[i+2]+b[j],但是a[i]+b[j+1]下一个状态a[i+1]+b[j+1]和a[i]+b[j+2],这样a[i+1]+b[j+1]就产生重复了,因此 * 就会产生多余的运算 * 3、优化的算法::如果当前a[i]+b[j]最小,下一个状态是a[i]+b[j+1],只有当i=0时,才加入下一个状态a[i+1]+b[j]。从而达到剪枝的目的 * 每次将可能的状态 * @param a 递增数组 * @param b 递增数组 * @param k 前k个最小值 */public static void compareMethod(int a[], int b[], int k) {class Node implements Comparable{private int aSub = 0;private int bSub = 0;private int value = 0;public Node(int aSub, int bSub, int value) {this.aSub = aSub;this.bSub = bSub;this.value = value;}@Overridepublic int compareTo(Object o) {Node node = (Node)o;if (this.value < node.value) return -1;else return 1;}}int count = 0;int c[] = new int[k];Queue<Node> queue = new PriorityQueue<Node>();queue.add(new Node(0, 0, a[0] + b[0]));//防止没有k个while(count < k && !queue.isEmpty()) {Node node = queue.poll();c[count++] = node.value;if (node.bSub + 1 < b.length) {queue.add(new Node(node.aSub, node.bSub + 1, a[node.aSub] + b[node.bSub + 1]));}if (node.bSub == 0 && node.aSub + 1 < a.length) {queue.add(new Node(node.aSub + 1, node.bSub, a[node.aSub + 1] + b[node.bSub]));}}for (int i = 0; i < k; i++) {System.out.print(c[i] + " ");}}/** * 算法复杂度k(log(k)) * 1、根据当前节点的状态,获取下一个可能的状态 * 2、一般的算法:如果当前a[i]+b[j]最小,下一个最小的状态可能是a[i+1]+b[j]或者a[i]+b[j+1]。如果这样的话就会产生重复,比如a[i+1]+b[j]下一个状态是 * a[i+1]+b[j+1]和a[i+2]+b[j],但是a[i]+b[j+1]下一个状态a[i+1]+b[j+1]和a[i]+b[j+2],这里有重复的项,主意清除重复的项。 *  * @param a 递增数组 * @param b 递增数组 * @param k 前k个最小值 */public static void compareMethodTwo(int a[], int b[], int k) {class Node implements Comparable{private int aSub = 0;private int bSub = 0;private int value = 0;public Node(int aSub, int bSub, int value) {this.aSub = aSub;this.bSub = bSub;this.value = value;}@Overridepublic int compareTo(Object o) {Node node = (Node)o;if (this.value < node.value) return -1;else return 1;}@Overridepublic boolean equals(Object o) {Node node = (Node)o;return this.aSub == node.aSub && this.bSub == node.bSub;}}int count = 0;int c[] = new int[k];Queue<Node> queue = new PriorityQueue<Node>();queue.add(new Node(0, 0, a[0] + b[0]));//防止没有k个while(count < k && !queue.isEmpty()) {Node node = queue.poll();c[count++] = node.value;if (node.bSub + 1 < b.length) {Node tmp = new Node(node.aSub, node.bSub + 1, a[node.aSub] + b[node.bSub + 1]);if (!queue.contains(tmp))queue.add(tmp);}if (node.aSub + 1 < a.length) {Node tmp = new Node(node.aSub + 1, node.bSub, a[node.aSub + 1] + b[node.bSub]);if (!queue.contains(tmp))queue.add(tmp);}}for (int i = 0; i < k; i++) {System.out.print(c[i] + " ");}}public static void main(String[] args) {int a[] = {10, 11, 12, 13, 17, 30};int b[] = {-5, -2, 0, 9, 10, 43};compareMethod(a, b, 5);System.out.println("");compareMethod(a, b, 5);System.out.println("");compareMethodTwo(a, b, 5);}}