从排序数组开始,确定值的出现次数。 [面试准备]

时间:2017-07-21 01:53:55

标签: arrays algorithm sorting

我最近接受了软件工程职位的采访,想要回顾一下我到达的问题和解决方案。

给定一个排序的数组(可能包含重复项),确定值在列表中出现的次数。

即。如果array = [1,1,2,3,3,3,4,5,6,6,7],列表中有多少3个

3 个答案:

答案 0 :(得分:7)

朴素的方法将使用for循环迭代整个列表,并在每次找到值时递增计数器。例如

def naiveCount(numbers, key):
    count = 0
    for n in numbers:
        if n == key:
            count += 1
    return count

我们承认,由于算法遍历数组中的每个值,因此它具有复杂性O(n)。然后他们问......你能做得更好吗?

因此,我们首先使用线索寻求更好的解决方案。我们获得了一个排序数组,这可以让我们了解一些可能比O(n)更好的搜索算法,也许是二进制搜索。

因此,我们可以对列表进行二进制搜索,并以成本O(logn)获取第一次出现该键的索引。从那里,我们可以向前走过数组并递增一个计数器,直到找到一个不等于键的值。如果密钥出现k次,我们会以O(logn + k)的复杂性结束。

此算法的一个示例包括二进制搜索和计数器,如下所示:

def binary_search(arr, key, low, high):
    if high >= low:
        middle = (low + high)/2
        if (middle == 0 or key > arr[middle -1]) and arr[middle] == key:
            return middle
        elif key > arr[middle]:
            return binary_search(arr, key, middle + 1, high)
        else:
            return binary_search(arr, key, low, middle - 1)
    return None

def countAfterSearching(numbers, key):
    count = 0
    firstIndex = binary_search(numbers, key, 0, len(numbers) - 1)
    if firstIndex == None:
        return count
    else:
        for n in numbers[firstIndex:len(numbers)]:
            if n > key:
                return count
            else:
                count += 1

面试官希望对你决定二元搜索的能力印象深刻,但会问“你能做得更好吗?”

我们已经知道二进制搜索以成本O(logn)找到第一个出现的索引。我们应该能够使用二进制搜索找到最后一个匹配的索引。减去这两个位置并加1将显示出现次数。

例如:

def binary_search_first(arr, key, low, high):
    if high >= low:
        middle = (low + high)/2
        if (middle == 0 or key > arr[middle -1]) and arr[middle] == key:
            return middle
        elif key > arr[middle]:
            return first(arr, key, middle + 1, high)
        else:
            return first(arr, key, low, middle - 1)
    return None

def binary_search_last(arr, key, low, high):
    if high >= low:
        middle = (low + high) / 2
        if (middle == len(arr) - 1 or key < arr[middle + 1]) and arr[middle] == key:
            return middle
        elif(key < arr[middle]):
            return last(arr, key, low, middle - 1)
        else:
            return last(arr, key, middle + 1, high)
    return None

def count(arr, key):
    rightmost = binary_search_last(arr, key, 0, len(arr)-1)
    leftmost = binary_search_first(arr, key, 0, len(arr)-1)
    return rightmost - leftmost + 1

此算法以复杂度O(logn)运行,这比2个提议的选项更好。

答案 1 :(得分:2)

一种非常简单的方法是执行以下操作:

>> array.count(3)

3

答案 2 :(得分:-1)

bisect module简化了这个问题:

Primary dropdown<select name="ForceSelection" id="ForceSelection" onChange="javascript:return setDropDown();">
<option value="" selected>Select</option>
<option value="treatmentid1">treatmentname1</option>
<option value="treatmentid2">treatmentname2</option>
</select> other dropdown
<select id="Qualifications" name="Qualifications">
    <option value="select">select</option>
    <option value="treatmentid1">treatmentname1</option>
    <option value="treatmentid2">treatmentname2</option>
</select> other dropdown2
<select id="Qualifications2" name="Qualifications2">
    <option value="select">select</option>
    <option value="treatmentid1">treatmentname1</option>
    <option value="treatmentid2">treatmentname2</option>
</select>