[谷歌访谈]如何在Python中找到峰值元素?

129 阅读5分钟

公司标签。Google, Microsoft, Facebook, Apple, Amazon, Bloomberg, Uber, Quora, Walmart Labs

据全球各地的程序员报道,在包括谷歌在内的一些巨型组织中,这是一个经常被问到的问题。如果这个问题也出现在你的面试中呢?你能以最佳方式解决这个问题吗?

问题说明

给定一个整数阵列nums ,找到一个峰值元素,并返回其索引。如果数组包含多个峰值,则返回任何一个峰值的索引。

  • 峰值元素是指严格大于其相邻元素的一个元素。

注意:你可以想象nums[-1] = nums[n] = -∞。

挑战。你 能写出一个能在**O(log n)**时间内运行的算法吗?

准则。

  • 1 <= nums.length <= 1000
  • -231 <= nums[i] <= 231 - 1
  • nums[i] != nums[i + 1] 为所有有效的i

例子

让我们来看看一些例子,以提高我们对这个问题的理解。

例1:
输入:nums = [1, 2, 3, 1
]输出。2
解释。3是一个峰值元素,你的函数应该返回索引数2.

例2:
输入:nums = [1, 2, 1, 3, 5, 6, 4]
输出。1或5解释
。你的函数可以返回索引号1或2,其中峰值元素分别为2和6。

例3:
输入:nums = [10, 12, 14, 16, 18]
输出。4
解释。18是一个峰值元素,你的函数应该返回索引号4.

例4:
输入:nums = [20, 15, 10, 5]
输出。0
解释:20是一个峰值元素,你的函数应该返回索引号0.

例子5:
输入:nums = [5, 5, 5]
输出。0、1或2
解释。你的函数可以返回任何索引,因为所有的元素都是一样的,因此每个元素都是一个峰值元素。





















方法1:使用线性搜索

**方法。**最简单的方法是在数组中使用线性搜索来寻找峰值元素。你必须遍历数组中的每一个元素,检查它是否大于其相邻的元素。如果是,则返回它。在解决这个问题时,有几个基础是你必须考虑的。

  1. 如果数组只包含一个元素,那么它将是峰值元素。
  2. 如果数组中的数字按升序排列(例3), 峰值元素将是最后一个。
  3. 如果数组中的数字按降序排列(例4),则峰值元素将是第一个元素。
  4. 如果数组中所有的元素都是一样的(例5), 每个元素都是一个峰值元素.

解决方法**:** 现在,让我们看看解决这个问题的代码。

def peak_element(nums):
    n = len(nums)
    if n == 1:
        return 0
    if nums[0] >= nums[1]:
        return 0
    if nums[n - 1] >= nums[n - 2]:
        return n - 1
    for i in range(1, n - 1):
        if nums[i] >= nums[i - 1] and nums[i] >= nums[i + 1]:
            return i

让我们在我们的例子上运行这段代码。

# 例一
nums = [1, 2, 3, 1
]print(peak_element(nums))
# 2

# 例
2nums = [1, 2, 1, 3, 5, 6, 4]
print(peak_element(nums))
# 1

# 例
3nums = [10, 12, 14, 16,18]
print(peak_element(nums))
# 4

# 示例
4nums = [20, 15, 10, 5]
print(peak_element(nums))
# 0

# 示例
5nums = [5, 5, 5]
print(peak_element(nums










))











# 0





















好哇!它通过了所有的测试案例。

复杂度分析。

  • 时间复杂度:在最坏的情况下,这个方法会遍历整个数组。因此,这个方法的时间复杂度将是O(n)
  • 空间复杂度。这个方法的空间复杂度是常数,即O(1)

讨论。总是有改进的余地。你能以比O(n)更好的复杂度找到峰值元素吗?

方法2:使用二进制搜索 [最佳解决方案]

**方法。**在这种方法中,你必须将数组的中间元素与它的相邻元素进行比较。当右边的邻居大于中间元素时,你将在右边找到峰值元素,当左边的邻居大于中间元素时,你将在左边找到峰值元素。在较大的邻接元素上递归应用同样的方法,直到找到峰值元素。

算法。

  1. 初始化左边为 0 ,右边为len(nums)-1
  2. 重复以下步骤,直到左数小于右数或找到峰值元素为止。
    • 将中间元素初始化为左+右/ 2,并检查中间元素是否是峰值元素。如果是,则返回它。
    • 如果nums[mid-1] > nums[mid] ,则将右元素设为right = mid – 1
    • 如果nums[mid+1] > nums[mid] ,则将左元素设为left = mid + 1

下图通过一个例子说明了上述算法的工作原理,比如给定的数组是[1,2,1,3,5,6,4]

解决方案。 现在,让我们看一下代码。

def peak_element(nums) :
    n = len(nums)
    left = 0
    right = n - 1
    while left <= right:
        mid = (left + right) // 2
        if (mid == 0 or nums[mid-1] <= nums[mid]) and (mid == n-1 or nums[mid] >= nums[mid+1]):  
            return mid
        if mid == 0 or nums[mid-1] > nums[mid]:  
            right = mid - 1
        else:  
            left = mid + 1

测试案例分析。 让我们在我们的例子上运行这段代码。

# 例子1
nums = [1, 2, 3, 1
]print(peak_element(nums))
# 2

#



示例
2nums = [1, 2, 1, 3, 5, 6, 4]
print(peak_element(nums))
# 5

# 示例
3nums = [10, 12, 14, 16,18]
print(peak_element(nums))
# 4

# 示例
4nums = [20, 15, 10, 5]
print(peak_element(nums))
# 0

# 示例
5nums = [5, 5, 5]
print(peak_element(nums










))











# 1





















是的!它通过了所有的测试案例。

复杂度分析。

  • 时间复杂度:在这个方法中,我们使用二进制搜索来寻找峰值元素。因此,时间复杂性将是O(logn)
  • 空间复杂度。这个方法的空间复杂度保持不变,即O(1)

结语

我希望你喜欢这个编码面试问题。请继续**关注并订阅更多**有趣的编码问题。

🎓文章来源:ShubhamSayon和Rashi Agarwal


推荐。Finxter计算机科学学院

  • Fiverr和Upwork上最抢手的技能之一是网络刮痧。不要搞错了。_以编程方式从网站中提取数据_是当今世界上由网络和远程工作塑造的关键生活技能。
  • 那么,你想掌握使用Python的BeautifulSoup进行网络搜刮的艺术吗?
  • 如果答案是肯定的--本课程将带领你从网络刮削的初学者变成专家。

现在就**加入BeautifulSoup的网络刮削大师班**,明天就可以掌握它了!

The post[Google Interview] How To Find the Peak Element In Python?first appeared onFinxter.