Monday, December 6, 2021

LeetCode Medium: Generate Parentheses

Dear followers,


Tonight, I came across a nice problem for post-dinner exercise, about generating all possible valid parentheses sequences given the number of brackets to use in total.

PROBLEM LINK: https://leetcode.com/problems/generate-parentheses/

PROBLEM SOLVING APPROACH: Recursion (using Choice Diagram and Decision tree)

TIME-COMPLEXITY: O(2^n) in the worst case but the input n is given to be max 8, so very much doable :)


Here's a sample Java solution for your reference:


class Solution {
    public List<String> generateParenthesis(int n) {
        ArrayList<String> generatedParentheses = new ArrayList<>();
        genParenthesesRecur(n, n, "", generatedParentheses);
        return generatedParentheses;
    }
    
    private void genParenthesesRecur (int remOpenBrackets, int remClosingBrackets, String outputFromCaller, List<String> generatedParentheses) {
        // Base Cases
        if (remOpenBrackets < 0 || remClosingBrackets < 0)
            return;
        
        if (remClosingBrackets < remOpenBrackets) {
            return;
        }
        
        if (remOpenBrackets == 0 && remClosingBrackets == 0) {
           generatedParentheses.add(outputFromCaller);
        }
        
        // Recursive Case
        String opUsingAnOpeningBracket = outputFromCaller + "(";
        genParenthesesRecur(remOpenBrackets-1, remClosingBrackets, opUsingAnOpeningBracket, generatedParentheses);
        if (remClosingBrackets > remOpenBrackets) {
            String opUsingAClosingBracket = outputFromCaller + ")";
            genParenthesesRecur(remOpenBrackets, remClosingBrackets-1, opUsingAClosingBracket, generatedParentheses);
        }
    }
}

Thanks for Reading!

Happy Programming!!


Love! ❤️ 
#Lets #Code

Follow us on :

https://twitter.com/ThinkAlgorithms


Sunday, December 5, 2021

Leetcode Easy: Longest Common Prefix

Tea-time snacking!


PROBLEM: https://leetcode.com/problems/longest-common-prefix/

TIME-COMPLEXITY: O(n*m) where n is the number of strings in input and m is the length of longest common prefix.


Sample Java Solution for tea-time snacking:


class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 1)
            return strs[0];
        
        int minLen = Integer.MAX_VALUE;
        for (int i=0; i<strs.length; i++) {
            minLen = Math.min(minLen, strs[i].length());
        }
        int lastPastIdx = minLen;
        outer:
        for (int i=0; i<minLen; i++) {
            char ch = strs[0].charAt(i);
            for (int str=0; str<strs.length; str++) {
                if (strs[str].charAt(i) != ch) {
                    lastPastIdx = i;
                    break outer;
                }
            }
        }
        return strs[0].substring(0, lastPastIdx);
    }
}

Enjoy and Happy Coding!!


Love! ❤️ 
#Lets #Code

Follow us on :

https://twitter.com/ThinkAlgorithms

Saturday, December 4, 2021

LeetCode Medium Trick Problem: Longest Consecutive Sequence



Came across this problem on Leetcode, which requires one to focus on optimization.


PROBLEM LINK: https://leetcode.com/problems/longest-consecutive-sequence

TIME COMPLEXITY: O(n) at worst case where n is the number of elements in the input array (precisely the constant factor for n is 2)

APPROACH: The most naive approach to solve this problem would have been to sort the input array using comparison sort in O(n lg n) worst case time complexity and then in single pass find the length of the consecutive sequences in the same, resulting in overall worst case time complexity on O(n lg n).

But, if we notice carefully, we can make use of a trick to solve the problem in O(n) worst case time complexity. The trick makes a space trade off of O(n) and makes use of a HashSet to store the values to quickly check if any number exists in the input array. Then, it checks for all values in input, if it is the start of a consecutive sequence by checking presence of 1 lesser value than that on the number line, in the number Set. If any start-of-consecutive-range is found in the array elements, the length of the range is found by consecutively checking all the numbers in the increasing order on the number line consecutively.

In each such iteration of the numbers in input array, the length of the max-range is updated and the largest value is returned at the end of all iterations.


Here's a sample code for the same:


class Solution {
    
    public int longestConsecutive(int[] nums) {
        Set numberSet = new HashSet ();
        
        // Add numbers to Set while updating length of the longest consecutive elements sequence
        int maxLLCES = 0, currLLCES = 0;
        for (int i=0; i<nums.length; i++) {
            numberSet.add (nums[i]);
        }
        
        for (int i=0; i<nums.length; i++) {
            if (!numberSet.contains(nums[i]-1)) {
                // nums[i] is not a start of a consecutive sequence
                currLLCES = 1;
                int checkNum = nums[i]+1;
                while(numberSet.contains(checkNum)) {
                    currLLCES++;
                    checkNum++;
                }
                maxLLCES = Math.max(maxLLCES, currLLCES);
                // System.out.println("Updated maxLLCES:" + maxLLCES);
            }
        }
        return maxLLCES;
    }
}



Do share your thoughts and feel free to talk about the alternatives/optimisations you feel can be done in the comment section!


Love! ❤️ 
#Lets #Code

Follow us on :

https://twitter.com/ThinkAlgorithms



Friday, December 3, 2021

Recursion Series: Deleting the middle element from a stack

This post marks the start point of the much awaited recursion series on Let'sCode_ =) 

We start it with a GeeksForGeeks problem : https://www.geeksforgeeks.org/delete-middle-element-stack/


Position of Middle element of all elements from top of stack (1 based):

stack.size()/2 + 1


Now, to build an effective solution we can use:

Methodology: Recursion

Time Complexity: O(n) where n is the number of elements in the stack

Space Complexity: O(n) considering the accumulation of constant space in each level of the recursive stack. O(1) if we dis-consider the stack space accumulation.


Here is one such solution:

<-- --todeletepos="" base="" case="" deletemidrecur="" int="" nteger="" printstack="" private="" return="" stack.pop="" stack.push="" stack="" static="" tack="" top="" void="">/*package whatever //do not write package name here */

import java.io.*;
import java.util.*;

class GFG {
	public static void main (String[] args) {
		System.out.println("GfG!");
		Stack<Integer> stack = new Stack<>();
		
		stack.push(6);
		stack.push(5);
		stack.push(4);
		stack.push(3);
		stack.push(2);
		stack.push(1);
		deleteMid(stack);
		
	}
	
	private static void deleteMid(Stack<Integer> stack) {
	    if (stack == null)
	        return;
	    if (stack.isEmpty())
	        return;
	        
	    int mid = stack.size()/2+1;
	    deleteMidRecur(stack, mid);
	    printStack(stack);
	}
	
	private static void deleteMidRecur (Stack<Integer> stack, int toDeletePos) {
	    if (toDeletePos == 1) {
	        // delete this element <-- base case
	        stack.pop();
	        return;
	    }
	    
	    int top = stack.pop();
	    deleteMidRecur(stack, --toDeletePos);
	    stack.push(top);
	}
	
	private static void printStack (Stack<Integer> stack) {
	    while (!stack.isEmpty()) {
	        System.out.println(stack.pop());
	    }
	}
}

IMO, such are the most efficient solutions to this problem. So share your thoughts and let me know your point of views.


Happy Coding!


Love! ❤️ 
#Lets #Code

Follow us on :

https://twitter.com/ThinkAlgorithms

 https://www.facebook.com/theAlgorithmicCoder

Wednesday, October 13, 2021

Beware of Multiple internet versions

Some time ago, I submitted an email to malwarebytes with data depicting the presence of multiple websites for an original tricking people into targetted scams.

In light of yesterday's (12 October, 2021's) news where malwareBytes admits and warns users of the same, I'd like to point out that not only for sites like the MalwareBytes.com site where one can be tricked into a duplicate site with malformed hyperlinks, even the Search Giant, Google's site has many duplicate websites, including 1 which I found my own internet pointing to on nslookup.


Here are the relevant screenshots worth the surprise:



Below you can see that my www.google.com entry points to the IP address whose reverse DNS lookup is the site-name which I have copied and hit with my web browser as seen in the above screenshot.


For your reference my /etc/resolv.conf, which is used for local entries for DNS lookup remained auto-generated, and looked like this (notice trail):


All-in-all:







Also, with today's announcement of the Honourable Prime Minister of India, where he warns everyone of cyber misinterpretation, such facts come to the rescue of the citizens of the world and provoke them to be more cautious by making them wary and aware!

Any such websites should be immediately reported and taken down from the internet's DNSes and a regular blacklisting of these should be automated and checked every very frequently on all the World Wide Web's DNSes in my honest opinion. Honestly said, the internet is not safe any more and it's even more evident with such data!


In light of the same, and for the lack thereof, to create more awareness and an actionable log of referable observations, Let's Code_ will be launching a dedicated platform where people will be able to report cybersecurity incidents.


Keep aware and stay safe!

Best of Love and Luck,

Yours Truly,
Chandni Verma
Chief Editor,
Let's Code_

#Lets #Code

Follow us on :


https://twitter.com/ThinkAlgorithms

Sunday, August 29, 2021

LeetCode Medium: Course Schedule

 The next problem in the current coding spree was:

Problem Name: Course Schedule

Problem Descriptionhttps://leetcode.com/problems/course-schedule/

Problem Approach used: Detecting cycles on the directed graph pf dependencies using DFS to solve in O(V+E) where V is the number of courses in the input and E is the number of edges between them.

Time ComplexityO(lg n) worst-case time and O(1) auxiliary space complexity


Java Solution:


//Cycle detection

// package com.projects.cv.course_schedule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Solution {

    // private static Logger logger = Logger.getLogger("MyLogger");
    int nodes;


    public boolean canFinish(int numCourses, int[][] prerequisites) {

        if (prerequisites == null)
            return false;
        int pL = prerequisites.length;
        nodes = numCourses;

        // Build directed graph
        Map<Integer, List<Integer>> g = new HashMap<>();
        for (int i=0; i<pL; i++) {
            if (!g.containsKey(prerequisites[i][0]))
                g.put(prerequisites[i][0], new ArrayList<>());
            g.get(prerequisites[i][0]).add(prerequisites[i][1]);
        }

        System.out.println(g);

        //Create visited to prevent re-visiting
        int visited[] = new int[numCourses];

        for (int i=0; i<numCourses; i++) {
            if (visited[i] == 0) {
                if (hasCycleDfs(g, visited, i, -1))
                    return false;
            }
        }

        return true;

    }

    private boolean hasCycleDfs( Map<Integer, List<Integer>> g, int[] visited, int n, int parent) {
        if (visited[n] == -1) {
            //current exploration path
            System.out.println("cycle found at u(" + parent + ")->v(" + n + ")");
            return true;
        }
        if (visited[n] == 1) {
            return false;
        }

        visited[n] = -1;

        if (g.get(n) == null) { // tackle bad callers
            visited[n] = 1;
            return false;
        }

        for (int neighBr : g.get(n)) {
            if (hasCycleDfs(g, visited, neighBr, n))
                return true;
        }

        visited[n] = 1;

        return false;
    }

    // public static void main(String[] args) {
    //     Solution s = new Solution();
    //     int[][] deps = {{1, 0}};
    //     s.canFinish(2, deps);
    // }

}



Love! ❤️ 
#Lets #Code

Follow us on :



https://twitter.com/ThinkAlgorithms

https://www.facebook.com/theAlgorithmicCoder

 




GeeksforGeeks Medium: Find the Number of Islands

Yesterday I solved a few hands-on coding problems using Java programming language.


I came across this easy problem(called Medium there) over GfG, to turn on the inertia:


Problem: Find the Number of Islands

Problem Descriptionhttps://practice.geeksforgeeks.org/problems/find-the-number-of-islands 

Problem Approach: DFS

Time Complexity: O(V) where v = number of cells in the input grid

One Java Solution:


// { Driver Code Starts
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine().trim());
        while(T-->0)
        {
            String[] s = br.readLine().trim().split(" ");
            int n = Integer.parseInt(s[0]);
            int m = Integer.parseInt(s[1]);
            char[][] grid = new char[n][m];
            for(int i = 0; i < n; i++){
                String[] S = br.readLine().trim().split(" ");
                for(int j = 0; j < m; j++){
                    grid[i][j] = S[j].charAt(0);
                }
            }
            Solution obj = new Solution();
            int ans = obj.numIslands(grid);
            System.out.println(ans);
        }
    }
}// } Driver Code Ends



class Solution
{
    int r, c;
    byte[] xOffset = {1, 1, 1, 0, -1, -1, -1, 0};
    byte[] yOffset = {1, 0, -1, -1, -1, 0, 1, 1};
    
    //Function to find the number of islands.
    public int numIslands(char[][] grid)
    {
        // Code here
        r = grid.length;
        c = grid[0].length;
        
        boolean[][] visited = new boolean[r][c];
        int cnt = 0;
        for (int i=0; i<r; i++) {
            for(int j=0; j<c; j++) {
                if (grid[i][j]=='1' && !visited[i][j]) {
                    dfs(grid, visited, i, j);
                    cnt++;
                }
            }
        }
        
        return cnt;
    }
    
    private void dfs (char[][] grid, boolean[][] visited, int x, int y) {
        //input validation
        if (!valid (grid, x, y) || visited[x][y]==true) {
            return;
        }
        
        visited[x][y] = true;
        
        for (int i=0; i<8; i++) {
            int newX = x + xOffset[i];
            int newY = y + yOffset[i];
            
            if(valid(grid, newX, newY) && !visited[newX][newY]) {
                dfs(grid, visited, newX, newY);
            }
        }
    }
    
    boolean valid (char[][]grid, int x, int y) {
        if (x<0 || x>=r || y<0 || y>=c || grid[x][y] == '0'){
            return false;
        }
        return true;
    }
}



Do share your thoughts and feel free to talk about the alternatives/optimisations you feel can be done in the comment section!


Love! ❤️ 
#Lets #Code

Follow us on :

https://twitter.com/ThinkAlgorithms
 https://www.facebook.com/theAlgorithmicCoder

 

 



Restarting Shorter and More Intense Problem-Solving Sprints

Hello Fellas,


After a long break, I have re-started #Problem #Solving #Tutorials using DS/Algorithms over (this) Let's Code Blog, but this time, it's gonna be consisting more intense but shorter #Coding #Sprints over weekends and somewhat lesser live-videos!! :D

Join me and get the weekend puzzle-solver activated in you!


✌️
#LetsCode

Sunday, February 14, 2021

HackerRank: Reverse a doubly linked list

Problem Description: https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list/problem

Runtime complexity of my below code: O(n) where n is the size of the linked list.

Solution approach: Recursive

My Java Solution:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;

public class Solution {

    static class DoublyLinkedListNode {
        public int data;
        public DoublyLinkedListNode next;
        public DoublyLinkedListNode prev;

        public DoublyLinkedListNode(int nodeData) {
            this.data = nodeData;
            this.next = null;
            this.prev = null;
        }
    }

    static class DoublyLinkedList {
        public DoublyLinkedListNode head;
        public DoublyLinkedListNode tail;

        public DoublyLinkedList() {
            this.head = null;
            this.tail = null;
        }

        public void insertNode(int nodeData) {
            DoublyLinkedListNode node = new DoublyLinkedListNode(nodeData);

            if (this.head == null) {
                this.head = node;
            } else {
                this.tail.next = node;
                node.prev = this.tail;
            }

            this.tail = node;
        }
    }

    public static void printDoublyLinkedList(DoublyLinkedListNode node, String sep, BufferedWriter bufferedWriter) throws IOException {
        while (node != null) {
            bufferedWriter.write(String.valueOf(node.data));

            node = node.next;

            if (node != null) {
                bufferedWriter.write(sep);
            }
        }
    }

    // Complete the reverse function below.

    /*
     * For your reference:
     *
     * DoublyLinkedListNode {
     *     int data;
     *     DoublyLinkedListNode next;
     *     DoublyLinkedListNode prev;
     * }
     *
     */
    static DoublyLinkedListNode reverse(DoublyLinkedListNode head) {
        return reverseRecur(head, head.next);
    }
    
    
    private static DoublyLinkedListNode reverseRecur(DoublyLinkedListNode current, DoublyLinkedListNode nextNode) { // 2, 3    3, 4   4, \0
        if (current == null)
            return current;

        if (nextNode == null && current.prev == null) {
            return current;
        }

        //Node nextNode = current.next; 2
        DoublyLinkedListNode prevNode = current.prev; // \0  1 2 3

        if (nextNode == null) {
            current.prev = null;
            return current;  // 4
        }

        //Assume reversed till current.
        DoublyLinkedListNode nextToNext = nextNode.next; // 4  \0

        // 1 <-> 2 <-> 3 <-> 4  ->   4<->3<->2<->1
        nextNode.next = current;  //4 <-> 3 <-> 2 <-> 1 -> \0
        current.prev = nextNode;
        current.next = prevNode;

        return reverseRecur(nextNode, nextToNext); // 3, 4    4, \0

    }


    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

        int t = scanner.nextInt();
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

        for (int tItr = 0; tItr < t; tItr++) {
            DoublyLinkedList llist = new DoublyLinkedList();

            int llistCount = scanner.nextInt();
            scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

            for (int i = 0; i < llistCount; i++) {
                int llistItem = scanner.nextInt();
                scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

                llist.insertNode(llistItem);
            }

            DoublyLinkedListNode llist1 = reverse(llist.head);

            printDoublyLinkedList(llist1, " ", bufferedWriter);
            bufferedWriter.newLine();
        }

        bufferedWriter.close();

        scanner.close();
    }
}



Do share your thoughts below!

Until next time, Happy Coding!


Saturday, January 23, 2021

LeetCode Medium: Open the Lock

 Another BFS solvable problem of LeetCode!


Problem Descriptionhttps://leetcode.com/problems/open-the-lock/

Problem Approach: BFS

Time Complexity: O(1) as the custom size of state-nodes in this problem is a constant.


Solution:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//public class OpenTheLock {
//}

import java.util.*;

class State {
    String code;
    int dist;
    State(String code, int dist) {
        this.code = code;
        this.dist = dist;
    }
}

class Solution {
    public int openLock(String[] deadends, String target) {

        Set<String> visited = new HashSet<>();
        Set<String> deadendsSet = new HashSet<>();
        for (String d : deadends) {
            deadendsSet.add(d);
        }

        if ("0000".equals(target))
            return 0;
        if (deadendsSet.contains("0000"))
            return -1;

        Queue<State> q = new LinkedList<>();
        q.add(new State("0000", 0));
        visited.add("0000");
        while (!q.isEmpty()) {
            State out = q.remove();
            List<String> neighbours = getNeighbours(out.code);
            for (String n : neighbours) {
                if (!visited.contains(n) && !deadendsSet.contains(n)) {
                    if (n.equals(target))
                        return out.dist+1;
                    State neighState = new State(n, out.dist+1);
                    visited.add(n);
                    q.add(neighState);
                }
            }
        }
        return -1;
    }

    private List<String> getNeighbours(String baseState) {
        List<String> res = new ArrayList<>();
        char[] codeChar = baseState.toCharArray();
        for (int i=0; i<codeChar.length; i++) {
            String neighState = new String();

            String c = ((codeChar[i]-'0')+1)%10 + "";
            for (int idx=0; idx<codeChar.length; idx++)
                if (idx == i)
                    neighState+=c;
                else
                    neighState+=codeChar[idx];
            res.add(neighState);

            neighState = new String();
            c = ((codeChar[i]-'0')+10-1)%10 + "";
            for (int idx=0; idx<codeChar.length; idx++)
                if (idx == i)
                    neighState+=c;
                else
                    neighState+=codeChar[idx];
            res.add(neighState);
        }
        return res;
    }

}


Have fun, until next time!

LeetCode Medium: Snakes and Ladders

Here's a problem based on the classical snakes and ladders children's game


Problem Descriptionhttps://leetcode.com/problems/snakes-and-ladders

Solution Approach: BFS

Time Complexity: O(V) where V is the number of cells in the board-game and E = 6V.


Solution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {
    public int snakesAndLadders(int[][] board) {
        int rows = board.length;
        int cols = board[0].length;
        int maxSq = rows*cols;
        
        boolean visited[] = new boolean[maxSq];
        int[] pred = new int[maxSq+1]; // Allows to print the path as well. Alternatively, a dist[] incrementing at each time can be used too.
        Queue<Integer> squaresQ = new LinkedList<>();
        squaresQ.add(1);
        visited[1] = true;
        pred[1] = 0;
        
        outer:
        while(!squaresQ.isEmpty()) {
            int sqOut = squaresQ.remove();
            
            for (int i=1; i<=6; i++) {
                int neighbourSq = sqOut + i;
                if (neighbourSq > maxSq)
                    break;
                
                int effRow = getEffRow(neighbourSq, rows, cols);
                int effCol = getEffCol(neighbourSq, rows, cols);
                if (board[effRow][effCol] != -1) {
                    neighbourSq = board[effRow][effCol];
                    effRow = getEffRow(neighbourSq, rows, cols);
                    effCol = getEffCol(neighbourSq, rows, cols);
                }
                if (neighbourSq == maxSq) {
                    pred[neighbourSq] = sqOut;
                    break outer;
                }
                
                if (!visited[neighbourSq]) {
                    visited[neighbourSq] = true;
                    pred[neighbourSq] = sqOut; // Alternatively, can do: dist[neighbourSq] = dist[sqOut]++;
                    squaresQ.add(neighbourSq);
                }
                
            }
        }
        
        int cnt = 0;
        int predSq = maxSq;
        if (pred[predSq] == 0)
            return -1;
        while(predSq != 1) {
            cnt++;
            predSq = pred[predSq];
        }
        
        return cnt;
    }
    
    private int getEffRow(int sq, int rows, int cols) {
       return (rows - 1 - (sq-1)/cols);
    }
    
    private int getEffCol(int sq, int rows, int cols) {
        int effCol = (sq -1) % cols; // 0 based
        
        if (((sq - 1)/cols + 1) % 2 == 0) // even row from bottom:1 based
            effCol = cols - 1 - effCol;
        
        return effCol;
    }
}


Until next time,

Happy Coding!

Monday, January 18, 2021

LeetCode Medium: Pancake Sorting

Problem of the day: Pancake Sorting

Problem description: https://leetcode.com/problems/pancake-sorting/

Solution Approach:

At every iteration for n-1 iterations move the max element in unsorted prefix array to the end of it by following the following steps:

  1. Find max element index in unsorted prefix part.
  2. flip array at that index.
  3. flip array at index marking the end of unsorted array.
  4. reduce the pointer marking end of unsorted array by 1 thereby decreasing the unsorted part of the array.

Solution:


  
  class Solution {
    public List<Integer> pancakeSort(int[] arr) {
        if (arr.length<=1) {
            return new ArrayList<>();
        }
        
        List<Integer> maxIndicesSelectedForFlip;
        
        int endOfUnsortedArray = arr.length-1;
        for (int idx=1; idx <= endOfUnsortedArray; idx++) {
            //find maxElement, maxElementIndex
            int maxElement = Integer.MIN_VALUE, maxElementIndex = -1;
            for (int i=0; i < endOfUnsortedArray; i++) {
                if (arr[i]>maxElement) {
                    maxElement = arr[i];
                    maxElementIndex = i;
                }
            }

            //Flip 0->maxElementIndex
            flip(arr, maxElementIndex);
            maxIndicesSelectedForFlip.add(maxElementIndex+1);

            //Flip 0->endOfUnsortedArray
            flip(arr, endOfUnsortedArray);
            maxIndicesSelectedForFlip.add(endOfUnsortedArray+1);
        }
        
        return maxIndicesSelectedForFlip;
        
    }
    
    private void flip(int[] arr, int maxIndex) {
        for (int i=0; i<=maxIndex/2; i++) {
            int tmp = arr[i];
            arr[i] = arr[maxIndex-i];
            arr[maxIndex-i] = tmp;
        }
    }
    
}
  
  

Time Complexity: O(n^2)

Space Complexity: In-place sorting: O(1) 


Happy Coding! ;)

Featured Post

interviewBit Medium: Palindrome Partitioning II

Problem Name:  Palindrome Partitioning II Problem Description : https://www.interviewbit.com/problems/palindrome-partitioning-ii/ Problem Ap...