题目如下:
给定一个已经升序排好序的数组,以及一个数 targettarget,如果 targettarget 在数组中,返回它在数组中的位置。
否则,返回 targettarget 插入数组后它应该在的位置。
假设数组中没有重复的数。以下是简单的示例:
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
输入格式
第一行输入一个整数 nn。
第二行输入 nn 个整数,表示数组A[n]
。
第三行输入 targettarget。
输出格式
输出一行,为要求返回的结果。
样例输入
3 1 3 5 2
样例输出
1
题目分析:一开始想到的是,利用二分查找遍历一遍数组,如果找到则返回;如果没有
找到,再遍历一遍数组,找到该元素应该插入的位置。所以,我写了如下代
码:
#include<stdio.h> #include<malloc.h> #include<assert.h> int findInsertPos(int arr[], int num, int target) { assert(arr); if (num <= 0) { printf("元素个数错误"); return -1;; } int left = 0; int right = num - 1; int i = 0; int minIndex = 0; while (left <= right) { int middle = (left & right) + ((left | right) >> 1); if (arr[middle] == target) { return middle; } else if (arr[middle] < target) { left = middle + 1; } else { right = middle - 1; } } for (i = 0; i < num; i++) { if (target < arr[i]) return i; } } int main() { int num = 0; int i = 0; int target = 0; int *arr = NULL; scanf("%d",&num); if(num > 0) { arr = (int *)malloc(num*sizeof(int)); if (NULL == arr) { printf("out of memory."); } } else return; for (i = 0;i < num; i++) { scanf("%d",arr+i); } scanf("%d",&target); int ret = findInsertPos(arr,num,target); printf("%d",ret); free(arr); arr = NULL; return 0; }
这段代码在我自己的vs下完全运行通过,并且可以得到正确的答案。然而,acm不通
过。总觉得运行超时,所以,利用GetTickCount()函数(所在的头文件:windows.h)
测试程序的运行时间,所得结果是远远超过题目的限时时间。
在草稿纸上推理一番:我们没有必要分情况,直接遍历一次就好了。acm通过的代码展
示:
#include<stdio.h> #include<malloc.h> #include<assert.h> int findInsertPos(int arr[], int num, int target) { assert(arr); if (num <= 0) { printf("元素个数错误"); return -1;; } int i = 0; for (i = 0; i < num; i++) { if (target <= arr[i]) return i; } } int main() { int num = 0; int i = 0; int target = 0; int *arr = NULL; int ret = 0; scanf("%d", &num); if (num > 0) { arr = (int *)malloc(num*sizeof(int)); if (NULL == arr) { printf("out of memory."); } } else return 0; for (i = 0;i < num; i++) { scanf("%d", arr + i); } scanf("%d", &target); if (ret >= 0) { ret = findInsertPos(arr, num, target); printf("%d", ret); } free(arr); arr = NULL; return 0; }
这样就符合题目要求,因为数组是升序,所以一趟循环就好了。题目看似和简单,但
是,算法最优就很重要了。
时间: 2024-10-10 12:54:43