【问题标题】:How to get the first and the last matching occurrence of an array in python?如何在python中获取数组的第一个和最后一个匹配项?
【发布时间】:2021-12-28 03:37:52
【问题描述】:

AirBNB 有一个面试问题:

你有一个排序数组,你想通过 python 中的函数获取元素匹配出现的第一个索引和最后一个索引。如果没有匹配,则返回 [-1.-1]。如果有匹配,则返回 [first_index,last_index]。

这是我的新手解决方案,谁能想出更好的解决方案?

顺便说一句,这个问题来自 TechLead DailyInterviewPro。

def solution(array,key):
    start_index = -1
    ending_index = -1
    if key not in array:
        return [start_index,ending_index]
    else:
        for i in range(len(array)):
            if array[i]==key:
                if start_index == -1:
                
                    start_index = i
                    ending_index = i
                else:
                    ending_index = i
                    
        return [start_index,ending_index]        

【问题讨论】:

  • 如果你正在准备编码,那么我建议你去Leetcode
  • @khelwood:list 没有rindexstr 提供indexrindex(以及类似的findrfind),但list 只提供index
  • @ShadowRanger 我的立场是正确的。

标签: python arrays list


【解决方案1】:

只是为了好玩,一个优化的解决方案:

  1. 使用index将确认至少一个值存在并检索其索引的工作推送到C层
  2. 避免扫描超出需要的单个元素,并且不制作任何副本(它根本不访问 start_indexend_index 之间的元素):
def solution(array,key):
    try:
        return [array.index(key),
                len(array) - next(i for i, x in enumerate(reversed(array), 1) if x == key)]
    except ValueError:
        return [-1, -1]

它依赖array.index 计算第一个元素的索引或提升ValueError(在这种情况下不存在这样的元素),然后以相反的顺序从运行在list 上的genexpr 检索单个值获取索引(genexpr 保证能找到某些东西,最坏的情况是它会一直运行,直到找到与 index 调用找到的相同元素)。从技术上讲,这确实意味着如果元素只出现一次,我们会对其进行两次相等性测试(来自两端),但避免说“成本”,虽然可以通过itertools.islice 进行,但几乎不值得费心。

如果你真的喜欢单线,你总是可以这样做的:

def solution(array,key):
    return [next((i for i, x in enumerate(array) if x == key), -1)
            next((len(array) - i for i, x in enumerate(reversed(array), 1) if x == key), -1)]

虽然该解决方案确实涉及在未找到元素时扫描整个array 两次(一次向前,一次向后)(如果元素存在,则扫描最少数量的元素)。

【讨论】:

  • 我认为这就是为什么 try except 在某些情况下更有用的原因。
【解决方案2】:

一个班轮,使用list.index函数你可以使用

[-1, -1] if key not in array else [arrary.index(key),len(array)-array[::-1].index(key)-1 ]

高效的代码,如果内存不是问题,否则需要使用两个指针方法

def solution(array, key):
    store_index = {}
    for index, value in enumarate(array):
         if value not in store_index:
              store_index[value] = []
         store_index[value].append(index)

    if key not in store_index:
       return [-1, -1]
    return [store_index[key][0], store_index[key][-1]]

【讨论】:

  • 哇,写的真简洁!
  • @Boyce 是的,但效率不高,需要读取数组多达 3 次,这在面试中肯定很重要。我猜招聘人员会更关心高效的可读代码,而不是 hacky 的单行代码;)
  • 是的,只是一个班轮效率不高,添加解决方案
  • 因此,与单行相比,这种方法在函数中创建了一个本地字典。并将键(要搜索的数组)存储为它的键,并存储它的所有索引,这些索引只遍历一次数组。太励志了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2022-01-03
  • 2017-02-13
  • 1970-01-01
相关资源
最近更新 更多