0% found this document useful (0 votes)
4 views13 pages

Array 06

The document discusses two algorithmic problems from LeetCode: 'Shortest Unsorted Continuous Subarray' and 'Next Permutation'. It provides problem statements, examples, and solutions with complexity analyses for both problems. The solutions include naive and optimized approaches, detailing the steps and observations necessary to achieve the desired outcomes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views13 pages

Array 06

The document discusses two algorithmic problems from LeetCode: 'Shortest Unsorted Continuous Subarray' and 'Next Permutation'. It provides problem statements, examples, and solutions with complexity analyses for both problems. The solutions include naive and optimized approaches, detailing the steps and observations necessary to achieve the desired outcomes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

ARRAY PRACTICE - 06

16 February 2024 17:21

1. SHORTEST UNSORTED CONTINEOUS


SUBARRAY ( LEETCODE-581 )

2. NEXT PERMUTATION ( LEETCODE-31 )

CREATED BY - SHIVAM BAREKAR


SHORTEST UNSORTED CONTINEOUS SUBARRAY (
LEETCODE-581 )
20 February 2024 21:05

Problem Statement : Given an integer array nums, you need to find one continuous
subarray such that if you only sort this subarray in non-decreasing order, then the
whole array will be sorted in non-decreasing order.
Return the shortest such subarray and output its length.

Link : Shortest Unsorted Continuous Subarray - LeetCode

Example 1 :

Input: nums = [2,6,4,8,10,9,15]


Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array
sorted in ascending order.

Example 2 :

Input: nums = [1,2,3,4]

Output: 0

Example 3 :
Input: nums = [1]
Output: 0

Constraints :

1 <= nums.length <= 104

-105 <= nums[i] <= 105


Solution-01 : Naive Approach :

Complexity Analysis :

Time complexity :
O(NlogN) -> As we are doing sort

Space complexity :
O(N) -> As we are using an extra array

Solution-02 : Better Approach :


Complexity Analysis :

Time complexity: O(N)


Space complexity: O(1)
As we are not using any additional array or space
NEXT PERMUTATION ( LEETCODE-31 )
20 February 2024 21:06

Problem Statement : A permutation of an array of integers is an arrangement of its


members into a sequence or linear order.

Link : Next Permutation - LeetCode

• For example, for arr = [1,2,3], the following are all the permutations of arr: [1,2,3],
[1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].

The next permutation of an array of integers is the next lexicographically greater


permutation of its integer. More formally, if all the permutations of the array are sorted
in one container according to their lexicographical order, then the next permutation of
that array is the permutation that follows it in the sorted container. If such arrangement
is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in
ascending order).

• For example, the next permutation of arr = [1,2,3] is [1,3,2].


• Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
• While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a
lexicographical larger rearrangement.

Given an array of integers nums, find the next permutation of nums.


The replacement must be in place and use only constant extra memory.

Example 1 :

Input: nums = [1,2,3]


Output: [1,3,2]

Example 2 :

Input: nums = [3,2,1]


Output: [1,2,3]

Example 3 :

Input: nums = [1,1,5]


Output: [1,5,1]
Constraints :

1 <= nums.length <= 100


0 <= nums[i] <= 100

Solution :

Algorithm / Intuition :

The steps are the following :

• Find the break-point, i: Break-point means the first index i from the back of the given
array where arr[i] becomes smaller than arr[i+1].
For example, if the given array is {2,1,5,4,3,0,0}, the break-point will be index 1(0-based
indexing). Here from the back of the array, index 1 is the first index where arr[1] i.e. 1 is
smaller than arr[i+1] i.e. 5.
To find the break-point, using a loop we will traverse the array backward and store the
index i where arr[i] is less than the value at index (i+1) i.e. arr[i+1].

• If such a break-point does not exist i.e. if the array is sorted in decreasing order, the
given permutation is the last one in the sorted order of all possible permutations. So, the
next permutation must be the first i.e. the permutation in increasing order.
So, in this case, we will reverse the whole array and will return it as our answer.

• If a break-point exists:
○ Find the smallest number i.e. > arr[i] and in the right half of index i(i.e. from index i+1
to n-1) and swap it with arr[i].
○ Reverse the entire right half(i.e. from index i+1 to n-1) of index i. And finally, return
the array.

Observation 1 :

Let’s try to observe some dictionary-ordered strings like “raj”, “rax”, and “rbx”. If we
carefully observe, we can notice that these strings contain a common prefix, and the
rankings are done based on the differentiating characters.

For example, “raj” and “rax” has a common prefix i.e. “ra” and the differentiating
characters are ‘j’ and ‘x’. Now, as ‘j’ appears before ‘x’ in the alphabet, “raj” appears before
“rax” in the given order. The same logic is applicable for “rax” and “rbx”(Common prefix:
“r”, differentiating characters: ‘a’ and ‘b’).

The same observation can be done on the permutations of numbers. For example, if the
array is [1, 2, 3], all possible permutations in sorted order will look like the following :

• [1, 2, 3]
• [1, 3, 2]
• [2, 1, 3]
• [2, 3, 1]
• [3, 1, 2]
• [3, 2, 1]

In the above cases, we can also notice that all the permutations contain an index i(between
the first and second last index) such that its right part is sorted in decreasing order.
Now, if we look at the array in the backward direction, it is sorted in increasing order up
to index i (from n-1 to index i+1).

We can call this index i as the break-point of the array. The left half of index i (the
length of the left half might be 0) in the current permutation is the same as in the
previous permutation. And the right half of the break-point is always in decreasing order.

The structure of every possible permutation is the following :

After all, we can conclude that the difference between the next and current permutation
always starts at the index i i.e. the break-point. How to find the break-point in an array :

We can clearly observe that the right half of the break-point will always be in decreasing
order. So, from the backside, the array will be in increasing order up to the break-point
index. Keeping this in mind, we will traverse the array from the backside and we will break
from the first index where arr[i] becomes smaller than arr[i+1]. The code will look like the
following :
Observation 2 :

If the break-point does not exist i.e. ind remains -1 in the code :
For an array that is sorted in decreasing order break-point does not exist. Here, we can
assure that the given array is the last one in the sorted order of all permutations. In this
case, the break-point index will be -1, the right half of the break-point will be the whole
array and the left half will be of length 0.
In this case, the next permutation should be as minimum as possible. So to achieve it, we
just need to reverse the whole array. And this will be our answer in this case. The code will
look like the following :

Observation 3 :

Until now, we have found the break-point where the difference starts in the permutations.
As the left half of the break-point should remain the same, we will not perform any
operation on the left half.

Now we need to modify the break-point and the right half to get the next permutation. By
the convention of ordering, we can say that the element at the break-point in the next
permutation should be the next greater element of arr[break-point] in the current
permutation.

Now to find the next greater element, we cannot use the whole array as the left half of
the break-point should remain the same. But we can use the right half as it can be
modified.

So, we will find the next greater element of arr[break-point] from the right half and swap
it with arr[break-point] itself. Next greater element of arr[break-point] means the
smallest element in the right half, greater than arr[break-point].
How to find and swap the next greater element of arr[break-point] :
The right half is sorted in decreasing order(or increasing order from the backside). So, we
will again traverse the array in the backward direction, and at the first index
where arr[index] > arr[break-point], we will swap arr[index] and arr[break-point].
The code will be the following :

For example, if the given array is {2, 1, 5, 4, 3, 0, 0}, the break-point will be index 1, and
the next greater element of arr[1] i.e. 1 is 3 from the right half. After swapping the array
will be like: {2, 3, 5, 4, 1, 0, 0}.

Observation 4 :

From the above example, we can observe that after swapping the right half remains sorted
in decreasing fashion as it was before. Until now, we have modified the break-point. Now
we are only left to modify the right half accordingly.
We want the permutation to be as close as possible to the given one. After swapping, the
new element at the break-point has already made it greater from the given permutation.
Now we want the right part to be the minimum possible and then only the permutation will
be the closest to the given one. Hence, we will simply reverse the entire right half to make
it ascending.

The code will be the following :


Finally, the above array will be like {2, 3, 0, 0, 1, 4, 5}.

Dry Run :

We will take the input array {1,3,2}.

Step 1: First find an increasing sequence. We take i1 = 1. Starting traversing backward.

Step 2: Since 3 is not less than 2, we decrease i1 by 1.

Step 3: Since 1 is less than 2, we achieved our start of the increasing sequence. Now, i1 =
0.
Step 4: i2 will be another index to find just greater than i1 indexed elements in the array.
Point i2 to the last element.
Step 5: i2 indexed element is greater than i1 indexed element. So, i2 has a value of 2.
Step 6: Swapping values present in i1 and i2 indices.

Step 7: Reversing from i1+1 index to last of the array.


Thus, we achieved our final answer.
Output :

The next permutation is: [2 3 0 0 1 4 5 ]

Complexity Analysis :

Time Complexity: O(3N), where N = size of the given array


Finding the break-point, finding the next greater element, and reversal at the end takes
O(N) for each, where N is the number of elements in the input array. This sums up to
3*O(N) which is approximately O(3N).

Space Complexity: Since no extra storage is required. Thus, its space complexity is O(1).

You might also like