九度OJ 1352:和为S的两个数字 (查找)
来源:互联网 发布:鬼谷战术风雨家淘宝 编辑:程序博客网 时间:2024/05/16 18:10
- 题目描述:
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
- 输入:
- 每个测试案例包括两行:第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和。其中1 <= n <= 10^6,k为int第二行包含n个整数,每个数组均为int类型。
- 输出:
- 对应每个测试案例,输出两个数,小的先输出。如果找不到,则输出“-1 -1”
- 样例输入:
6 151 2 4 7 11 15
- 样例输出:
4 11
思路:
朴素思路是遍历查找,也就是我最初代码中用的方法。复杂度NlogN。
但后来想想,其实根据4xy = (x+y)^2-(x-y)^2,两个数的和一定,那么差越大,积越小,其实只需要找差最大的这一对数即可。可以省掉很多多余的查找。但最坏的复杂度仍然是NlogN。
进一步的优化思路能够将复杂度下降到线性:两个数A和B分别从最左侧和最右侧向中间搜索,每次循环中,固定A,从上次搜索到的B开始下降搜索。最终的复杂度将是N。
PS:这个题的测试数据不是太好,我试了朴素思路和优化思路,结果竟然相差不大。
代码:
#include <stdio.h> #define N 1000000 int search(int *a, int begin, int end, int x){ int len = end - begin; if (len <= 0) return -1; if (len == 1) { if (a[begin] == x) return begin; else return -1; } int mid = begin + len/2; if (a[mid] == x) return mid; else if (x < a[mid]) return search(a, begin, mid, x); else return search(a, mid+1, end, x);} int main(void){ int n, k, i, j; int a[N]; while (scanf("%d%d", &n, &k) != EOF) { for(i=0; i<n; i++) scanf("%d", &a[i]); for (i=0; i<n-1; i++) { j = search(a, i+1, n, k-a[i]); if (j > i) break; else continue; } if (i == n-1) printf("-1 -1\n"); else printf("%d %d\n", a[i], a[j]); } return 0;}/************************************************************** Problem: 1352 User: liangrx06 Language: C Result: Accepted Time:1520 ms Memory:4748 kb****************************************************************/
优化代码:
<pre name="code" class="cpp">#include <stdio.h> #define N 1000000 int main(void){ int n, k, i, j; int a[N]; while (scanf("%d%d", &n, &k) != EOF) { for(i=0; i<n; i++) scanf("%d", &a[i]); i = 0, j = n-1; while (i < j) { if (a[i] + a[j] == k) break; else if (a[i] + a[j] < k) i++; else j--; } if (i == j) printf("-1 -1\n"); else printf("%d %d\n", a[i], a[j]); } return 0;}/************************************************************** Problem: 1352 User: liangrx06 Language: C Result: Accepted Time:1450 ms Memory:4748 kb****************************************************************/
0 0
- 九度OJ 1352:和为S的两个数字 (查找)
- 九度OJ 1352 和为S的两个数字
- 九度OJ - 1352 - 和为S的两个数字
- 【剑指Offer面试编程题】题目1352:和为S的两个数字--九度OJ
- 九度OJ-题目1352:和为S的两个数字
- 题目1352:和为S的两个数字-九度
- 九度 题目1352:和为S的两个数字
- 九度 题目1352:和为S的两个数字
- 九度 题目1352:和为S的两个数字
- 九度 题目1352:和为S的两个数字
- 九度笔记之 1352:和为S的两个数字
- 【LeetCode】Two Sum && 【九度】题目1352:和为S的两个数字
- 九度_题目1352:和为S的两个数字
- 九度题目:和为S的两个数(1352)
- 和为S的两个数字
- 和为S的两个数字
- 找出和为S的两个数字
- 和为S的两个数字
- Hadoop2.7.1集群安装
- 进程与线程的区别(面试高频问题)
- javax.xml.ws.soap.SOAPFaultException: Cannot create a secure XMLInputFactory
- 数据链路层的是三个基本问题
- AndroidStudio与GitHub
- 九度OJ 1352:和为S的两个数字 (查找)
- 单线程读fifo写文件
- ajax的基础:XMLHttpRequest对象
- Linux设备驱动程序简介
- 魔方阵
- C 专家编程的一些小知识点
- android 图片缩放手势
- android 转场之transition
- 1032. Sharing (25)