Shifted Array Search (pramp)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值