[经典面试题]排序数组中绝对值最小元素

【题目】


题目为:

有一个已经排序的数组(升序),数组中可能有正数、负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现

例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4。

【分析】

给定数组是已经排好序的,且是升序,没有重复元素。

一个简单的思路,就是一次性遍历数组,求出数组的元素的绝对值的最小值,这样的时间复杂度为O(n)。

但是,这样就浪费了题目的一个条件:数组是已经排好序的。所以,需要对原来的题目进行转换。考虑到数组有序,利用二分查找原理。

求数组中绝对值最小的元素,与0离得最近绝对值越小。基于这个原理设计代码。

分三种情况:

(1)如果全是正数,返回第一个元素值。if(A[0] >= 0)   

(2)如果全是负数,返回最后一个元素值。if(A[n-1] <= 0)

(3)有正有负,利用二分查找找到0的插入位置,如果正好找到0的位置,0就是绝对值最小的元素,

如果没有找到0,插入位置的左右元素比较绝对值大小 ,返回较小者OK。

【代码】

/*********************************
*   日期:2015-01-29
*   作者:SJF0115
*   题目: 排序数组中绝对值最小元素
*   来源:百度
*   博客:
**********************************/
#include <iostream>
#include <algorithm>
using namespace std;

int MinAbs(int A[],int n){
    if(n == 1){
        return A[0];
    }//if
    // 只有正数
    if(A[0] >= 0){
        return A[0];
    }
    // 只有负数
    if(A[n-1] <= 0){
        return A[n-1];
    }
    // 找到0的插入位置
    int target = 0;
    int left = 0,right = n - 1;
    int mid;
    while(left <= right){
        mid = left + (right - left) / 2;
        // 中间元素等于目标
        if(A[mid] == target){
            return A[mid];
        }
        // 目标在左半部分
        else if(A[mid] > target){
            right = mid - 1;
        }
        // 目标在右半部分
        else{
            left = mid + 1;
        }
    }//while
    // 绝对值最小
    if(abs(A[left]) < abs(A[right])){
        return A[left];
    }
    return A[right];
}

int main(){
    //int A[] = {-6,-5,-4,-3,-2,-1};
    //int A[] = {-6,-5,-4,1,2,3};
    //int A[] = {1,2,3,4,5,6};
    int A[] = {-20,-13,-4,6,77,200};
    int n = 6;
    cout<<MinAbs(A,n)<<endl;;
    return 0;
}
时间: 2025-01-19 19:34:18

[经典面试题]排序数组中绝对值最小元素的相关文章

百度面试题:求一个已排序的数组中绝对值最小的元素

题目为: 有一个已经排序的数组(升序),数组中可能有正数.负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现 例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4. 这一题该如何求呢? 初步的解决思路是:     1.数组中的元素全为正,取最左边的数字:     2.数组中的元素全为负,取最右边的数字的绝对值:     3.数组中有正数有负数,就用二分法查找,判断中间元素的符号        a)中间元素为

java去除已排序数组中的重复元素_java

题目描述 给定一个已排序的数组,去除数组中的重复元素,只保留一个重复的元素,并且返回新的数组长度. 要求: 不要给数组分配额外的空间,你必须使用常量的内存大小进行原地操作. 例如: 给出数组A=[1,1,2],你的函数调用之后必须返回长度length=2,并且A现在变成[1,2]. 输入 一个已排序的数组,例如[1,1,2]. 输出 返回数组新的长度,例如length=2. 快慢指针法 设置fast指针遍历数组,slow指针指向不重复元素的下一位. public static int remov

求数字在排序数组中出现的次数

题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小.1<=n <= 10^6. 第二行有n个整数,表示数组元素,每个元素均为int. 第三行有1个整数m,表示接下来有m次查询.1<=m<=10^3. 下面有m行,每行有一个整数k,表示要查询的数. 输出: 对应每个测试案例,有m行输出,每行1整数,表示数组中该数字出现的次数. 样例输入: 8 1 2 3 3 3 3 4 5 1 3 样例输出: 4 我做这道题,是先用二

如何求数字在排序数组中出现的次数

题目: 统计一个数字在排序数组中出现的次数. 通过折半查找, 找到首次出现的位置, 再找到末次出现的位置, 相减即可. 时间复杂度O(logn). 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <stdlib.h> #include <string.h> int GetFirstK

c语言-冒泡排序可以这样写吗,我只对结构体数组中某一个元素进行排序,然后交换

问题描述 冒泡排序可以这样写吗,我只对结构体数组中某一个元素进行排序,然后交换 struct troop { char name[1]; int a[3]; }tro[4]; void bubblesort(int a, int b, int c) { struct troop temp; int i, j; for (i=a; i { for (j=a+1; j { if (tro[j].a[c] > tro[i].a[c]) { temp = tro[j]; tro[j] = tro[i];

剑指offer系列之三十六:数字在排序数组中出现的次数

题目描述 统计一个数字在排序数组中出现的次数. 因为是排序数组,自然联想到二分查找算法,这样我们在二分的时候可能会获取多个相同的数字.就是说,中间那个位置的值可能刚好是统计的那个值,假设为k.那么k还有可能在前面或者后面出现,在这个基础上继续二分当然也是可以的,如果能够在使用二分查找算法的时候统计出第一个k和最后一个k出现的位置,那么k出现的次数自然就确定了.第一个k出现的位置,可以使用二分查找算法,如果中间位置的值刚好是k,那么继续比较中间位置前面位置的值是不是也是k,如果不是那么该中间位置就

PHP去除数组中重复的元素并按键名排序函数_php技巧

1.此函数的作用:去除数组中重复的元素并按键名排序 function assoc_unique($arr, $key) { $tmp_arr = array(); foreach($arr as $k => $v) { if(in_array($v[$key], $tmp_arr)) { unset($arr[$k]); } else { $tmp_arr[] = $v[$key]; } } sort($arr); return $arr; } 使用例子: $aa = array( array(

《剑指offer》-数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数. 首先吐槽下出题人的用词,啥叫排序数组?"排序"是个动词好么,"有序"作为一个形容词表示状态,修饰"数组",才是合适的. 题目考察二分查找,首先找到指定数字最先出现的位置,然后找到最后出现的位置,他们的距离+1就是个数. class Solution14{ public: int GetNumberOfK(vector<int> data, int k){ if (data.empty()){ re

PHP去除数组中的空值元素(array

说来惭愧,以前在去掉数组的空值是都是强写foreach或者while的,利用这两个语法结构来删除数组中的空元素,简单代码如下: <?php foreach($arr as $k=>$v){ if(!$v) unset($arr[$k]); } 事实证明如果数组过大的情况下这样处理的效率并不高.因为foreach是将当前操作的数组进行copy,每操作一下foreach,都是copy了一个变量,页面里面如果有太多的foreach,会是一个很大的消耗. 在网上闲逛的时候,看到人有提示用array_f