📌  相关文章
📜  范围和查询以K索引逆时针旋转Array(1)

📅  最后修改于: 2023-12-03 15:41:26.343000             🧑  作者: Mango

范围和查询以K索引逆时针旋转Array

本篇文章主要介绍如何在有序旋转数组中进行范围和查询以及以K索引逆时针旋转数组的算法实现。

有序旋转数组

有序旋转数组是指一个本来是有序的数组,但是经过旋转之后,变成了一个既可能顺时针旋转到末尾,也可能逆时针旋转到了末尾的数组。

例如,原始的有序数组为[1,2,3,4,5],经过旋转后可能变成[3,4,5,1,2]或者[4,5,1,2,3]等等。

范围和查询

在有序旋转数组中进行范围和查询可以使用二分查找的思想。我们可以先把数组分为两段,然后分别在两段中二分查找对应的值的位置,最后计算出对应范围的和。

算法实现如下:

def range_sum(nums, left, right):
    if not nums or left > right:
        return 0
    
    # 找到旋转点
    rotate_point = find_rotate_point(nums)
    if rotate_point == len(nums) - 1:
        return sum(nums[left:right+1])
    
    # 分别在左半段和右半段中进行二分查找
    l, r, mid = 0, rotate_point, 0
    while l <= r:
        mid = (l + r) // 2
        if nums[mid] < nums[rotate_point]:
            r = mid - 1
        else:
            l = mid + 1
    
    left_part = nums[:l]
    l, r, mid = rotate_point, len(nums) - 1, 0
    while l <= r:
        mid = (l + r) // 2
        if nums[mid] > nums[rotate_point - 1]:
            l = mid + 1
        else:
            r = mid - 1
            
    right_part = nums[r+1:]
    
    # 计算范围和
    ans = 0
    if len(left_part) > left:
        ans += sum(left_part[left - 1:])
    if len(right_part) >= right + 1:
        ans += sum(right_part[:right])
    return ans

下面是函数的输入和输出示例:

nums = [5, 6, 7, 1, 2, 3, 4]
print(range_sum(nums, 2, 5))  # 输出 6+7+1+2=16
逆时针旋转数组

在有序旋转数组中逆时针旋转数组可以使用三次翻转的方法。

算法实现如下:

def rotate_array(nums, k):
    if not nums or k < 0:
        return nums
    
    k %= len(nums)
    
    def reverse(start, end):
        while start < end:
            nums[start], nums[end] = nums[end], nums[start]
            start += 1
            end -= 1
    
    reverse(0, len(nums) - 1)
    reverse(0, k - 1)
    reverse(k, len(nums) - 1)

下面是函数的输入和输出示例:

nums = [1, 2, 3, 4, 5, 6, 7]
rotate_array(nums, 3)
print(nums)  # 输出[5, 6, 7, 1, 2, 3, 4]

以上就是范围和查询以K索引逆时针旋转Array的算法介绍,希望能对大家有所帮助。