华为od机试-整数对最小和

给定两个整数数组 array1 array2

数组元素按升序排列

假设从array1 array2中分别取出一个元素可构成一对元素

现在需要取出K个元素

并对取出的所有元素求和

计算和的最小值

注意:

两对元素如果对应于array1 array2中的两个下标均相同,则视为同一个元素

输入描述

输入两行数组array1 array2

每行首个数字为数组大小 size( 0 < size <= 100)

0 < array1(i) <= 10000 < array2(i) <= 1000

接下来一行为正整数k (0 < k <= array1.size() * array2.size())

输出描述

满足要求的最小和

示例一

3 1 1 2

3 1 2 3

2

输出

4

思路解析和复杂度分析

思路解析

这道题可以看做是两个有序数组的归并排序的变形。先将两个数组中的元素两两相加,得到 m×nm×n 个元素,将这些元素按和的大小升序排序。题目要求取出前 kk 个元素的和的最小值。

因为数组是有序的,可以考虑使用双指针法,用两个指针 ii 和 jj 分别指向数组 AA 和数组 BB,从头开始依次枚举每个元素,记录当前已经选取的元素个数 cntcnt。每次选取两个指针指向的元素中较小的一个,将其加入答案中,并将所在数组的指针向后移动一位。当 cntcnt 达到 kk 时停止。

复杂度分析

排序的时间复杂度为 O(mnlog⁡(mn))O(mnlog(mn)),枚举的时间复杂度为 O(k)O(k),因此总时间复杂度为 O(mnlog⁡(mn)+k)O(mnlog(mn)+k)。当 kk 远小于 m×nm×n 时,算法的时间复杂度较低,但当 kk 接近 m×nm×n 时,算法效率较低。

空间复杂度为 O(mn)O(mn),因为需要开辟一个数组来存储每个元素的和以及对应的下标。

import java.util.*;

public class Main {

static class Node {

int i, j, val;

public Node (int i, int j, int val) {

this.i = i;

this.j = j;

this.val = val;

}

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int m = sc.nextInt();

int[] arr1 = new int[m];

for (int i = 0; i < m; i++) {

arr1[i] = sc.nextInt();

}

int n = sc.nextInt();

int[] arr2 = new int[n];

for (int i = 0; i < n; i++) {

arr2[i] = sc.nextInt();

}

int k = sc.nextInt();

Node[] nodes = new Node[m * n];

int nodesLen = 0;

for (int i = 0; i < m; i++) {

for (int j = 0; j < n; j++) {

nodes[nodesLen++] = new Node(i, j, arr1[i] + arr2[j]);

}

}

Arrays.sort(nodes, new Comparator<Node>() {

public int compare(Node a, Node b) {

return a.val - b.val;

}

});

int ans = 0;

boolean[] used = new boolean[m];

int cnt = 0;

for (int i = 0; i < nodesLen; i++) {

if (used[nodes[i].i]) continue;

ans += nodes[i].val;

used[nodes[i].i] = true;

cnt++;

if (cnt == k) break;

}

System.out.println(ans);

}

}

全部评论

相关推荐

09-23 08:56
已编辑
国家开放大学 Java
题目描述如果三个正整数A、B、C&nbsp;,A²&nbsp;+&nbsp;B²&nbsp;=&nbsp;C²&nbsp;则为勾股数,如果ABC之间两两互质,即A与B,A与C,B与C均互质没有公约数,则称其为勾股数元组。请求出给定&nbsp;n&nbsp;~&nbsp;m&nbsp;范围内所有的勾股数元组。输入描述起始范围1&nbsp;&lt;&nbsp;n&nbsp;&lt;&nbsp;10000n&nbsp;&lt;&nbsp;m&nbsp;&lt;&nbsp;10000输出描述ABC保证A&nbsp;&lt;&nbsp;B&nbsp;&lt;&nbsp;C输出格式A&nbsp;B&nbsp;C多组勾股数元组,按照A&nbsp;B&nbsp;C升序的排序方式输出。若给定范围内,找不到勾股数元组时,输出Na。import&nbsp;java.util.Scanner;public&nbsp;class&nbsp;Main&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Scanner&nbsp;in&nbsp;=&nbsp;new&nbsp;Scanner(System.in);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(in.hasNextInt())&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;n&nbsp;=&nbsp;in.nextInt();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m&nbsp;=&nbsp;in.nextInt();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;found&nbsp;=&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;n;&nbsp;i&nbsp;&lt;=&nbsp;m;&nbsp;i++)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;j&nbsp;=&nbsp;i&nbsp;+&nbsp;1;&nbsp;j&nbsp;&lt;=&nbsp;m;&nbsp;j++)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;k&nbsp;=&nbsp;(int)&nbsp;Math.sqrt(i&nbsp;*&nbsp;i&nbsp;+&nbsp;j&nbsp;*&nbsp;j);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(k&nbsp;&gt;&nbsp;m)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(k&nbsp;*&nbsp;k&nbsp;==&nbsp;i&nbsp;*&nbsp;i&nbsp;+&nbsp;j&nbsp;*&nbsp;j)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(gcd(i,&nbsp;j)&nbsp;==&nbsp;1&nbsp;&amp;amp;&amp;amp;&nbsp;gcd(j,&nbsp;k)&nbsp;==&nbsp;1)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf(&amp;quot;%d&nbsp;%d&nbsp;%d\\n&amp;quot;,&nbsp;i,&nbsp;j,&nbsp;k);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found&nbsp;=&nbsp;true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!found)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&amp;quot;Na&amp;quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;int&nbsp;gcd(int&nbsp;a,&nbsp;int&nbsp;b)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;b&nbsp;==&nbsp;0&nbsp;?&nbsp;a&nbsp;:&nbsp;gcd(b,&nbsp;a&nbsp;%&nbsp;b);&nbsp;&nbsp;&nbsp;&nbsp;}}
投递华为等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务