Shifted Array Search (pramp)

该文章描述了一个在左移排序数组中查找特定元素的问题,提出了通过找到分割点然后应用二分搜索的方法。时间复杂度为O(log(N)),空间复杂度为O(1)。

Algorithms practice:pramp

Description

Shifted Array Search
A sorted array of distinct integers shiftArr is shifted to the left by an unknown offset and you don’t have a pre-shifted copy of it. For instance, the sequence 1, 2, 3, 4, 5 becomes 3, 4, 5, 1, 2, after shifting it twice to the left.

Given shiftArr and an integer num, implement a function shiftedArrSearch that finds and returns the index of num in shiftArr. If num isn’t in shiftArr, return -1. Assume that the offset can be any value between 0 and arr.length - 1.

Explain your solution and analyze its time and space complexities.

Example

input: shiftArr = [9, 12, 17, 2, 4, 5], num = 2
shiftArr is the outcome of shifting [2, 4, 5, 9, 12, 17] three times to the left
output: 3 #

Constraints

[time limit] 5000ms
[input] array.integer arr
[input] integer num
[output] integer

hints

A common mistake is to try to solve by concatenating the shifted array to itself. E.g. [9, 12, 17, 2, 4, 5, 9, 12, 17, 2, 4, 5] for the example above. While this might seem right at first glance, there isn’t really a good way to identify the part of the array that we need to focus on in order to find the index of num.
If your peer is stuck, ask them how they’d go about finding a number in a regular (i.e. unshifted) sorted array. Hint: Binary Search.
If your peer doesn’t understand binary search, go ahead and explain it to them. Be sure to reduce their rating on ‘problem solving’ in the feedback from, though.
Make sure that your peer fully implements the binary search algorithm since they’re going to need it anyway as part of the full solution.
Watch out for mistakes with index calculations, e.g. division results not rounded, going out of an array bounds, forgotten indices etc.
To be considered optimal, the solution must achieve O(log((N)) time complexity.

code

Oral process of solving problems

Shifted Array Search
For a shifted array, binary search cannot be straightforwardly applied, since it’s no longer sorted. Instead, what we can do is to choose “smartly” a pivot point where the shifted array will be partitioned precisely into two fully sorted (in an ascending order) sub-arrays. Once done, we apply binary search on the relevant sub-array.

For instance, for the example above, the pivot point is index 3 and two sub-arrays are [9, 12, 17] and [2, 4, 5]. Notice that each array is indeed fully sorted.

So how do we choose a pivot point? Well, the desired pivot point is the index that satisfies the following condition: shiftArr[i-1] > shiftArr[i]. There could be maximum only one such index since the values are distinct and the array was shifted to the left.

To find the pivot point, we could easily scan shiftArr linearly until we find an index that meets the condition above. However, a more efficient way will be to use modified version of binary search. On each step, we check whether the current shiftArr[i] is smaller than its left neighbor. If it is, then we we’ve found our pivot.

Otherwise, we determine what half of the array we need to focus on by comparing shiftArr[mid] to shiftArr[0]. This comparison will tell us if the current mid index is part of the shifted sub-array or the other sub-array.

Once we have found the pivot point and split the array, we can apply binary search only on the relevant sub-array and ignore the other sub-array. The relevant sub-array would satisfy: subArr[0] ≤ num ≤ subArr[n-1].

Pseudocode:

function shiftedArrSearch(shiftArr, num):
    pivot = findPivotPoint(shiftArr)

    if(pivot == 0 OR num < shiftArr[0]):
        return binarySearch(shiftArr, pivot, shiftArr.length - 1, num)
    
    return binarySearch(shiftArr, 0, pivot - 1, num)


function findPivotPoint(arr):
    begin = 0
    end = arr.length - 1

    while (begin <= end):
        mid = begin + floor((end - begin)/2)
        if (mid == 0 OR arr[mid] < arr[mid-1]):
            return mid
        if (arr[mid] > arr[0]):
            begin = mid + 1
        else:
            end = mid - 1

    return 0


function binarySearch(arr, begin, end, num):
    while (begin <= end):
        mid = begin + floor((end - begin)/2)
        if (arr[mid] < num):
            begin = mid + 1
        else if (arr[mid] == num):
            return mid
        else:
            end = mid - 1

    return -1

Time Complexity: the time complexity of findPivotPoint is O(log((N)) since it’s essentially a slightly modified version of the binary search algorithm. The time complexity of binarySearch is obviously O(log((N)) as well. The total time complexity is therefore O(log((N)).

Space Complexity: throughout the entire algorithm we used only a constant amount of space, hence the space complexity is O(1).

words

link

### Shifted Windows 的概念 Shifted Windows 是一种用于处理时间序列数据的技术,特别适合于涉及长时间依赖关系的任务。该方法通过滑动窗口的方式遍历整个时间序列,在每次移动时创建一个新的子序列作为输入特征的一部分。这种方法不仅能够捕捉到局部模式,还能有效保留全局结构信息。 对于给定长度为 \( T \) 的时间序列 \( X=\{x_1, x_2,...,x_T\} \),设定窗口大小 \( w \) 和步长 \( s \),则可以从起始位置开始每隔 \( s \) 步选取连续的 \( w \) 个元素形成一个新片段\( Y_i = \{y_{i-w+1}, y_{i-w+2},...,y_i\}\)[^1]。 这种机制允许算法更灵活地探索不同时间段内的变化规律,并有助于缓解传统固定窗口方法可能带来的边界效应问题。 ### Python 实现示例 下面是一个简单的 Python 函数来展示如何实现 shifted windows: ```python import numpy as np def create_shifted_windows(data, window_size=50, stride=1): """ 创建shifted windows 参数: data (list or array): 输入的时间序列数据. window_size (int): 单个window包含的数据点数量,默认值为50. stride (int): 移动步幅,默认值为1. 返回: list of lists: 每个列表代表一个由原时间序列中相邻元素组成的window. """ n_elements = len(data) # 计算可以产生的最大windows数目 max_num_windows = ((n_elements - window_size)//stride)+1 result = [] for i in range(0,max_num_windows*stride,stride): if(i+window_size<=len(data)): temp=data[i:i+window_size] result.append(temp) return result # 测试函数 data_series = [i for i in range(1, 101)] # 假设有一个简单的时间序列数据集 windows = create_shifted_windows(data_series, window_size=10, stride=3) print(f"Number of created windows:{len(windows)}") for idx, win in enumerate(windows[:3]): print(f"Window {idx}: {win}") ``` 上述代码定义了一个 `create_shifted_windows` 函数,它可以接收任意一维数组形式的时间序列数据并按照指定参数生成对应的 shifted windows 结果。这里设置了一个较小的例子来进行测试输出前几个窗口的内容以便观察效果[^2]。 ### 应用场景 Shifted Windows 技术广泛应用于各种基于时间序列分析的任务当中,尤其是在那些需要考虑较长时间跨度内动态行为的情况下表现尤为突出。具体来说,这包括但不限于以下几个方面: - **金融预测**:利用历史股价走势对未来价格变动做出预估; - **天气预报**:依据过往气象记录推测短期内气候条件的变化趋势; - **电力负荷估计**:根据用电量的历史统计数据规划发电机组运行计划; - **物联网设备监控**:实时跟踪传感器读数以检测异常情况的发生概率等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值