解决leetcode第4017题数组中的峰值II

4017.数组中的峰值II

难度:困难

问题描述:

给你一个长度为n的整数数组nums和一个二维整数数组queries。

如果满足以下条件,子数组numsi..j被称为峰值子数组:

其长度至少为3。

存在一个下标k使得i<k<j且:

numsk>numsk-1

numsk>numsk+1

你需要处理以下两种类型的查询:

1,li,ri:计算完全包含在numsli..ri中的峰值子数组的数量。

2,indexi,vali:将numsindexi更新为vali。此更新适用于所有后续查询。

返回一个数组answer,其中answeri是按出现顺序排列的第i个类型1查询的答案。

子数组是数组中连续的非空元素序列。

示例1:

输入:nums=1,3,2,4,queries=\[1,0,3,2,1,1,1,0,3]

输出:2,0

解释:

查询1,0,3:

1,3,2:选择k=1。则numsk=3,numsk-1=1,且numsk+1=2。因为3>1且3>2,这是一个峰值子数组。

1,3,2,4:选择k=1。则numsk=3,numsk-1=1,且numsk+1=2。因为3>1且3>2,这是一个峰值子数组。

查询2,1,1:将nums1更新为1。数组变为1,1,2,4。

查询1,0,3:现在没有峰值子数组。

因此,answer=2,0。

示例2:

输入:nums=9,8,9,8,queries=\[1,1,3,2,2,1,1,0,2]

输出:1,0

解释:

查询1,1,3:

nums1..3=8,9,8:选择k=2。则numsk=9,numsk-1=8,且numsk+1=8。因为9>8且9>8,这是一个峰值子数组。

查询2,2,1:将nums2更新为1。数组变为9,8,1,8。

查询1,0,2:没有峰值子数组。

因此,answer=1,0。

示例3:

输入:nums=3,6,2,7,1,queries=\[1,1,3,2,3,0,1,0,4]

输出:0,3

解释:

查询1,1,3:唯一长度至少为3的子数组是6,2,7。其唯一可能的峰值下标是k=2,但nums2=2小于nums1=6和nums3=7,因此它不是一个峰值子数组。

查询2,3,0:将nums3更新为0。数组变为3,6,2,0,1。

查询1,0,4:

3,6,2:选择k=1。则numsk=6,numsk-1=3,且numsk+1=2。因为6>3且6>2,这是一个峰值子数组。

3,6,2,0:选择k=1。则numsk=6,numsk-1=3,且numsk+1=2。因为6>3且6>2,这是一个峰值子数组。

3,6,2,0,1:选择k=1。则numsk=6,numsk-1=3,且numsk+1=2。因为6>3且6>2,这是一个峰值子数组。

因此,answer=0,3。

提示:

3<=n==nums.length<=10**5

0<=numsi<=10**5

1<=queries.length<=10**5

queriesi=1,li,ri或queriesi=2,indexi,vali

0<=li<ri<=n-1

0<=indexi<=n-1

0<=vali<=10**5

分析问题:

解决下面几个小问题,这道题也就迎刃而解了。

一是对于一个数组,先找出其中有多少个峰值,把索引号0和峰值对应的索引号以及最后一个元素的索引号n-1以列表的形式返回,如果中间没有峰值,则返回空列表,函数get_list_of_peak_index(nums1)实现这一功能;

二是对于只有一个峰值的数组nums2,k=start,peak,end,描述了一个查询,如何把这个查询中的不同峰值子数组数量统计出来呢?函数get_numbers_of_peak_sub_array(k,nums2)实现这一功能,最后返回统计出来的峰值子数组数量t和不同的子数组列表temp;

三是处理第一种查询1,li,ri,先根据查询,取出对应的子数组,然后查出子数组中的峰值列表,把这个峰值对应的索引号列表比如0,i1,i2,i3,......,in,n-1,分解成多个小部分,0,i1,i2、i1,i2,i3、i2,i3,i4、......,每一个部分只有一个峰值,然后调用函数get_numbers_of_peak_sub_array(k,nums2)依次统计每个小部分中峰值子数组的数量,最后将所有峰值子数组数量加起来,就是这个查询对应的峰值子数组的总数量,返回总数量和对应的峰值子数组列表temp;

四是处理第二种查询2,indexi,vali],函数get_changed_nums(query2,nums)实现了这一功能,返回新的nums;

主程序根据查询序列queries,依次取出查询,调用相应的查询处理函数,输出每次查询结果,问题得到解决。

程序如下:

python 复制代码
#统计一个数组nums中峰值子数组的峰值索引号列表t并返回
def get_list_of_peak_index(nums1):
    t=[0]
    n=len(nums1)
    for i in range(n-1):
        if nums1[i] > nums1[i - 1] and nums1[i] > nums1[i + 1]:
            t.append(i)
    t.append(n-1)
    if len(t)<3:
        return []
    else:
        return t

# 统计一个最大的峰值数组nums中峰值子数组的数量并返回
def get_numbers_of_peak_sub_array(k,nums2):
    n=len(nums2)
    start=k[0]
    peak=k[1]
    end=k[2]
    t=(peak-start)*(end-peak-1)
    temp=[]
    for i in range(start,peak):
        for j in range(peak+1,end):
            sub_array=nums2[i:j+1]
            temp.append(sub_array)
    return t,temp

#对查询[2,indexi,vali]的处理,返回处理之后的nums
def get_changed_nums(query2,nums):
    nums[query2[1]]=query2[2]
    return nums

#对查询[1,li,ri]的处理,返回处理之后得到的完全包含其中的峰值子数组数量
def get_numbers_of_peak_subarray_by_query(query1,nums3):
    nums4=nums3[query1[1]:query1[2]+1]
    t = get_list_of_peak_index(nums4)
    if not t:
        return 0,[]
    else:
        n = 0
        r = len(t)
        temp=[]
        for i in range(r - 2):
            a = t[i]
            b = t[i + 1]
            c = t[i + 2] + 1
            k = [a, b, c]
            m, e = get_numbers_of_peak_sub_array(k, nums4)
            temp.extend(e)
            n += m
        return n,temp

#主程序
nums=eval(input('pls input nums='))
queries= eval(input('pls input queries='))
t=[]
for query in queries:
    if query[0]==1:
        n,a=get_numbers_of_peak_subarray_by_query(query,nums)
        s='有以下峰值子数组:' if n!=0 else '没有峰值子数组'
        print(f'对于查询{query},{s}')
        if a:
            print(a)
        t.append(n)
    else:
        k=nums[::]
        nums=get_changed_nums(query,nums)
        print(f'对于查询{query},使得原数组{k}变为{nums}')
print('answer =',t)

运行实例一

pls input nums=1,3,2,4

pls input queries=\[1,0,3,2,1,1,1,0,3]

对于查询1, 0, 3,有以下峰值子数组:

\[1, 3, 2\], \[1, 3, 2, 4\]

对于查询2, 1, 1,使得原数组1, 3, 2, 4变为1, 1, 2, 4

对于查询1, 0, 3,没有峰值子数组

answer = 2, 0

运行实例二

pls input nums=9,7,9,7,9,2

pls input queries=\[1,0,3,2,1,10,1,0,5]

对于查询1, 0, 3,有以下峰值子数组:

\[9, 7, 9, 7\], \[7, 9, 7\]

对于查询2, 1, 10,使得原数组9, 7, 9, 7, 9, 2变为9, 10, 9, 7, 9, 2

对于查询1, 0, 5,有以下峰值子数组:

\[9, 10, 9\], \[9, 10, 9, 7\], \[9, 10, 9, 7, 9\], \[10, 9, 7, 9, 2\], \[9, 7, 9, 2\], \[7, 9, 2\]

answer = 2, 6

运行实例三

pls input nums=3,6,2,7,1

pls input queries=\[1,1,3,2,3,0,1,0,4]

对于查询1, 1, 3,没有峰值子数组

对于查询2, 3, 0,使得原数组3, 6, 2, 7, 1变为3, 6, 2, 0, 1

对于查询1, 0, 4,有以下峰值子数组:

\[3, 6, 2\], \[3, 6, 2, 0\], \[3, 6, 2, 0, 1\]

answer = 0, 3

相关推荐
威哥爱编程9 分钟前
模拟面试智能体开发实战 02:回答等半分钟,谁还愿意练?把服务端和流式输出搭起来
python·agent·harmonyos
威哥爱编程18 分钟前
模拟面试智能体开发实战 01:面试挂了都不知道挂在哪?用 Python 给自己造一个随叫随到的 AI 面试官
python·agent·harmonyos
2601_9679801140 分钟前
Python行情API量化 02:顺序拉 20 要 2 秒?并发批量把时间压到 0.5 秒
python·api·限流·并发·量化
伞伞悦读43 分钟前
【第81期】特征缩放怎么选:标准化、MinMax 与 Robust 的原理、泄漏对照和完整实验
人工智能·python·深度学习·机器学习
新*1 小时前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
武子康2 小时前
驾驶轨迹换个坐标,就能给移动机器人用吗?
人工智能·算法·机器学习
卷无止境3 小时前
mathmodel-figure-templates 以及两个上手案例
后端·python
锋行天下4 小时前
服务器 Python 2.7 装不了 langgraph-cli?用本地生成 Dockerfile 曲线救国
人工智能·后端·python
一条大祥脚4 小时前
深入理解 PyTorch FlexAttention:从 Score Mod 到 Mask Mod 的稀疏加速之道
人工智能·pytorch·python·注意力机制·flex attention·可编程注意力
文丑颜不良啊5 小时前
LeetCode2461~2480题目解析
java·leetcode