• Skip to main content
  • Skip to primary sidebar
BMA

BeMyAficionado

Inspire Affection

Almost Sorted Hacker Rank Problem (Medium Difficulty)

November 27, 2020 by varunshrivastava Leave a Comment

Recently I came across this problem in hacker rank. This problem is really fascinating as it teaches you to handle a lot of edge cases and variables at the same time. So, I thought of writing an article on this one. I hope you will enjoy it as much as I enjoyed solving it.

Table of Contents

  • Simplified Problem Statement
    • Easy Approach
    • Step 1 – Find Points Where Order Changes
    • Case 1 – SWAP Two Numbers
    • Case 2 – REVERSE Sub-Array
    • Final Code

Simplified Problem Statement

You will be given an array of N integers. This array could be completely sorted or almost sorted as the problem states.

If the array is sorted then it is fantastic you don’t have to do anything but if the array is not sorted then you are left with 2 options –

  • Perform a swap operation
  • Perform a reverse operation

But you can only perform any one of the above operations and you can perform them once. And once you have performed the operation the final array should be sorted.

The output of the program should be in one of the below formats:

yes
swap {index1} {index2}

Or,

yes
reverse {index1} {index2}

Or,

no

The problem seems complicated just by reading it. But if you spend some time with the problem you start to see a pattern.

Easy Approach

The problematic area in the above problem is to identify the points from where the order changes from ascending to descending and then from descending to ascending.

Sorted array approach is the easiest one when it comes to identifying these ups and downs in the array.

Step 1 – Find Points Where Order Changes

The easiest approach is to sort the given array.

As you can see in the image below.

I’ve sorted the array and then compared their indices. And whenever there was a mismatch in the value I recorded the start and end position. Along with the start and end position, I also counted the number of mismatches.

This count variable will later help us to differentiate between SWAP and REVERSE operation.

Step One - sort the array and compare indices
Step One – sort the array and compare indices

The code to fetch the above information is as follows:

vector<int> sorted_arr = arr;
sort(sorted_arr.begin(), sorted_arr.end());

int start = -1, end = -1, count = 0, len = sorted_arr.size();

for (int i=0; i < len; i++) {
    if (sorted_arr[i] != arr[i]) {
        if  (start == -1) start = i;
        else end = i;

        count++;
    }
}    

Once you have the above information regarding the start pointer, end pointer and count, you can write the code to identify which operations to perform to sort the array.

Let’s start with the first case.

Case 1 – SWAP Two Numbers

This case is straightforward once you have the count information with you.

All you have to check is that the count==2.

Step One - sort the array and compare indices
Step One – sort the array and compare indices

If the count is 2 it means that there are only two places where the array values mismatched. This means that there is a probability that if we swap these two values, we might get the sorted array.

But mind you there are a lot of edge cases in the above scenario. You will have to cover all the edge cases otherwise your program will break.

The code for the above check is as followed:

    if (count == 2) {
        // next to each other
        if ((start == 0  && end - start == 1) || 
            (end == len - 1 && end - start == 1) || 
            (start > 0 && end == len - 1 && arr[end] > arr[start - 1]) ||
            (arr[start] < arr[end + 1] && arr[end] > arr[start - 1])) {
            return "yes\nswap " + to_string(start + 1) + " " + to_string(end + 1);
        } 

        return "no";
    }

The conditions do look complex but they are actually there to take care of the edge conditions.

The edges conditions are mostly the start and end indices of the array.

In the simplest condition to check and see if the swap operation will sort the array is to check the following:

arr[start] < arr[end - 1] AND arr[end] > arr[start - 1]

If the above condition is satisfied then swap operation can be performed successfully. The rest is just to take care of the edge cases.

Case 2 – REVERSE Sub-Array

The reverse operation is a little bit more complex as it involves one extra step to test that the subarray (5..2) is actually a sorted array in the descending order. Take a look at the below example:

Case 2 - Check the reverse subarray
Case 2 – Check the reverse subarray

This check is simple. And if the sub-array is not stored then it means that the array cannot be sorted by a reverse operation. So, we will return “no” and we are done.

for (int i = start; i < end; i++) 
        if (arr[i] < arr[i+1]) return "no";

But if the sub-array is in descending order then we will have to perform certain checks to make sure that the reverse operation will sort the array.

Again, there are edge cases because of which the conditions start to look daunting but it really isn’t. The thing that we are checking is this:

arr[end] > arr[start - 1] AND arr[start] < arr[end  + 1]

This means that (from the above array) 2 should always be bigger than 1. And 5 should always be smaller than 6. If this condition is satisfied then the reversing the subarray will definitely result in a sorted array.

The code for the same is as follows:

    if ((start == 0 && end == len - 1)                                  || 
            ((start == 0 && end + 1 < len) && arr[start] < arr[end + 1])    || 
            ((end == len - 1 && arr[end] > arr[start - 1]))                 || 
            (arr[end] > arr[start - 1] && arr[start] < arr[end  + 1]))
                return "yes\nreverse " + to_string(start + 1) + " " + to_string(end + 1);
        
        return "no";

Final Code

So, the final pieces of the code are –

  • Sort the array
  • Find the indices where the values are different
  • Keep track of the first mismatch and the last mismatch.
  • Keep track of the number of mismatches.
  • Solve for SWAP case
  • Solve for the REVERSE case

Time Complexity – O(nlogn)

There is an O(n) solution available but I will leave that for you to implement.

When we merge our code together this is what we get:

string almost_sorted_nlogn(vector<int> &arr) {
    vector<int> sorted_arr = arr;
    sort(sorted_arr.begin(), sorted_arr.end());

    int start = -1, end = -1, count = 0, len = sorted_arr.size();

    for (int i=0; i < len; i++) {
        if (sorted_arr[i] != arr[i]) {
            if  (start == -1) start = i;
            else end = i;

            count++;
        }
    }

    if (count == 2) {
        // next to each other
        if ((start == 0  && end - start == 1) || 
            (end == len - 1 && end - start == 1) || 
            (start > 0 && end == len - 1 && arr[end] > arr[start - 1]) ||
            (arr[start] < arr[end + 1] && arr[end] > arr[start - 1])) {
            return "yes\nswap " + to_string(start + 1) + " " + to_string(end + 1);
        } 

        return "no";
    }

    if (count > 2) {
        // to check if the segment is in decreasing order
        for (int i = start; i < end; i++) 
            if (arr[i] < arr[i+1]) return "no";
        
        if ((start == 0 && end == len - 1)                                  || 
            ((start == 0 && end + 1 < len) && arr[start] < arr[end + 1])    || 
            ((end == len - 1 && arr[end] > arr[start - 1]))                 || 
            (arr[end] > arr[start - 1] && arr[start] < arr[end  + 1]))
                return "yes\nreverse " + to_string(start + 1) + " " + to_string(end + 1);
        
        return "no";
    }

    return "no";
}

The code is really simple and easy to implement. The only tough thing about this problem was to come up with a solution to find the places where the mismatch of the values starts and ends.

After that, you just have to take care of the edge cases and the code works.

Here’s my submission on Hackerrank – passed all test cases.2020-11-25

Hackerrank solution passes all the test cases
Hackerrank Solution passes all the test cases

Do comment below if you are stuck somewhere or just want to start a discussion around another approach.

Related

Filed Under: Programming Tagged With: almost-sorted, hackerrank, problem-solving

Primary Sidebar

Subscribe to Blog via Email

Do you enjoy the content? Feel free to leave your email with me to receive new content straight to your inbox. I'm an engineer, you can trust me :)

Join 874 other subscribers

Latest Podcasts

Recent Posts

  • Is The Cosmos a Vast Computation?
  • Building Semantic Search for E-commerce Using Product Embeddings and OpenSearch
  • Leader Election with ZooKeeper: Simplifying Distributed Systems Management
  • AWS Serverless Event Driven Data Ingestion from Multiple and Diverse Sources
  • A Step-by-Step Guide to Deploy a Static Website with CloudFront and S3 Using CDK Behind A Custom Domain

Recent Comments

  • Varun Shrivastava on Deploy Lambda Function and API Gateway With Terraform
  • Vaibhav Shrivastava on Deploy Lambda Function and API Gateway With Terraform
  • Varun Shrivastava on Should Girls Wear Short Clothes?
  • D on Should Girls Wear Short Clothes?
  • disqus_X5PikVsRAg on Basic Calculator Leetcode Problem Using Object-Oriented Programming In Java

Categories

  • Blogging
  • Cooking
  • Fashion
  • Finance & Money
  • Programming
  • Reviews
  • Software Quality Assurance
  • Technology
  • Travelling
  • Tutorials
  • Web Hosting
  • Wordpress N SEO

Archives

  • November 2024
  • September 2024
  • July 2024
  • April 2024
  • February 2024
  • November 2023
  • June 2023
  • May 2023
  • April 2023
  • August 2022
  • May 2022
  • April 2022
  • February 2022
  • January 2022
  • November 2021
  • September 2021
  • August 2021
  • June 2021
  • May 2021
  • April 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • February 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • January 2019
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016

Tags

Affordable Hosting (4) algorithms (4) amazon (3) aoc-2020 (7) believe in yourself (4) best (4) database (4) earn money blogging (5) education (4) elementary sorting algorithms (4) experience (3) fashion (4) finance (6) Financial Freedom (7) food (7) friends (3) goals (5) google (5) india (10) indian cuisine (5) indian education system (4) java (16) life (16) life changing (4) love (4) make money (3) microservices (9) motivation (4) oops (4) podcast (6) poor education system (4) principles of microservices (5) problem-solving (7) programmer (5) programming (28) python (5) reality (3) seo (6) spring (3) success (10) success factor (4) technology (4) top 5 (7) typescript (3) wordpress (7)

Copyright © 2025 · Be My Aficionado · WordPress · Log in

Go to mobile version