Compute The Next Permutation of A Numeric Sequence - Case Analysis ("Next Permutation" on Leetcode)

Back To Back SWE · Beginner ·⚡ Algorithms & Data Structures ·7y ago

Key Takeaways

This video teaches how to compute the next permutation of a numeric sequence using case analysis and the next permutation algorithm on Leetcode

Full Transcript

All right. So in today's problem, we are going to look at the problem next permutation. How do we generate the next permutation given a sequence that we already have? So if our sequence is 1 2 and 3, the next permutation in that sequence is going to be 1 3 and 2. If I have 3 2 1 as my permutation that I'm given, the next permutation in the sequence is the first permutation because this is the last permutation of the numbers 1 2 and 3. This is the last permutation. So we just return the empty array. There is no next permutation. 1 5 and 2. What is the next permutation? The next permutation is 215. When you're looking at these, you might not see a pattern. And I myself, I do not see a pattern. But we do not see a pattern until we understand how permutations are built. All right. So we have two choices to this problem. We first we can generate every single permutation until we hit the permutation we are given and then we go one step forward. That will give us the next permutation. The problem with that approach is we're going to be doing factorial time work. n factorial* n whatever work we're doing in our base case or our individual calls but we are going to go through at worst n factorial permutations if we're given the last permutation and this is a very expensive way to go about things. The point of this problem is not to have you brute force it like this. The point of the problem is to see whether you really know how a permutation is built and whether you can do a in-depth case analysis. If you have not seen my video on building permutations and permuting a string, I highly recommend that because that will help you a lot with understanding what goes on here. But let's investigate now. Let's start connecting the dots and see how is a permutation built. So if we're given 1 2 and three, what we need to do is we need three slots. The point of a permutation is to exhaust the possibilities of placing each one of these letters in a slot and then recursing and then placing the rest of the numbers. So here's an example. At the first position, we have the choice of placing the one, the two, or the three. When we're doing it like this, temporal order gets preceded. So we're going to place the first item, the least item, which is one. So I want you to notice something. One is not in our possibility space. We are at the second slot. We only have two choices. We have two slots. We have two choices. And at this second slot, we can either put a two or a three. We can either put a two or a three. Notice that. So what you see here is we planted a one. And that's exactly where our permutation stands in its state right now. They decided to plant a one. And notice they decided to plant a two. So at this position, we either could plant the two or three. The decision was made by this person or however this permutation panned out to place the two. At this position, at this state, it holds a state. It is currently exploring the number of ways it can place two and then recurse. We place the two and we explore all possibilities. And then after we place the two, our decision space is down to three. Now all we can place here is a three. Let's place the three. And now we have exhausted our decision space at this slot. All we could place is the three. So now we ask ourselves the question. We ask ourselves what is the next permutation to 1 2 3. Now do you notice how we understand more about the problem? we understand more about the state that the permutation we are sitting in came from. Where did it derive from? What state is this slot in? This slot is in the state of exploring the placement of two. Notice that we have exhausted all the placements. All we could place here is three. We've done three. So, what we need to do to find the next permutation is backtrack one. Okay, we backtracked one. And again, we're going to get to the core algorithm, but I just need you to understand this walkthrough. So, we got through the three and now this slot is empty. Three is back in the decision space. And notice we planted on two. We explored all of the possibilities that two's placement had to offer, which was placing a three here. And now two has exhausted itself. And the two returns to the decision space. So now we can use either two and or three at this position. The next thing to place is going to be a three. Before it was two. Two did all of its exploring. This was on its last permutation. And now we place the three. And now notice three is not in our decision space anymore. And now all we can place here is two. And so now 1 3 and two. So what is the overarching state? The overarching state is we planted a one. What else could we have planted here? We could have planted two or three. So all the while we're doing our exploring over here, we are doing it off of the planting one. While we're doing our exploring here, we're doing it off the planting three. While we're exploring here, we're doing our planting off of two. It is all about planting and exploring possibilities. So this is the next permutation. So let me ask you, what would the permutation after this be? So what we notice is that a section that is decreasing has exhausted itself and reached its last placement. If we try to find the next permutation, what we would do is we would need to see where we need to backtrack. So what we do is we notice the two has exhausted all of the possibilities. So we need to erase two and return it to the pool. And notice we have no more things to explore at the second slot. We've tried the two, we've tried the three, so we erase the three. And so now we have explored all of the possibilities with one rooted in the first slot. Now what is the next item to get rooted? Two is the next item to get the rooting. And now our decision space has adjusted itself. Two gets the planting. We are now exploring on two. And now we have two choices for the second placement. We can place the one or the three. And now we choose precedence on the lesser item. So one gets the placement. And then all we can put in the last slot is three. That's all we have left. So this is the next next permutation. This is the permutation after the permutation we just made. So I want you to start noticing a pattern. What we're doing is we're looking for a strictly decreasing section because that is the section that has exhausted itself. This has exhausted itself. So this would get erased. So the element before the strictly decreasing section is the element that still has options to explore. So now the next option would be to explore the three and then so on. So what we notice is the item right before a strictly decreasing section is the item of interest. That is what we need to do our modulation on in order to advance us to the next permutation because the strictly decreasing section has exhausted itself. the item before that section has items that it can swap between. It still has more choices for its slot. So, let's look at a concrete example to see this pattern. So, this is a very tricky case analysis problem. This is not something where you just instantly know the answer. And I need you to make a few intellectual jumps here so that you can really let this sink in. So, what we just noticed is each of the decisions are plantings. So imagine I am given this permutation. We'll see why these are important. But notice this person said let me plant six. It goes out of our decision space. They said let me plant two. It goes out of our decision space. They said let me plant one. And then one disappeared from the decision space. But notice here this item is before a strictly decreasing section. Remember we just established a strictly decreasing section is on its last permutation. If this section is on its last permutation, what do we need to modulate? We need to modulate what is right before that strictly decreasing section. Why? So when we are at slot number three, we have these choices. We already expressed all of zero's decisions. If we are on one, if we chose one to be placed in the slot, we have passed all of zero. Zero is behind us. That's not going to be on our next permutation planting. We need to consider what is the next item that we planned here. So these are the items left to us that were cut out of our decision space. So we have a 1 3 4 and a five. And notice our one is the item that was chosen. So the next item to take one's position. The position right before the strictly decreasing section. The item is the next greatest item to the right of one. What is the next greatest item? The next greatest item is three. So, we look for the item that is the next greatest item in the decreasing section. We look for three because guess what? Three is next up in line to get the placement at this slot. And then four will get a placement and then five. So, what we do is we swap these items. We swap the one and a three. So, that three gets its placement. It is next. Okay. So now we've almost completely simulated going to the next permutation. We've swapped the next rooting before the decreasing section. But notice that this is on the last permutation if we were going to plant at three. So what we need to do is turn this strictly decreasing section into an increasing section. So we are on the first permutation of planting at three. This would be the last permutation planting at three. We want to be at the first permutation planting at three. So we reverse this sublist. We don't need to sort it. We can just reverse it because it's already in reverse sorted order. And so now this is how we find the next permutation. Notice we've only done linear time operations. We're not going into factorial time complexity. We've been able to use case analysis to stay linear in how we solve the problem. So three got its next rooting and the suffix has been minimized. When it is decreasing, it is maximized. It is on the end of itself. But when it is increasing, then we have minimized this. We have minimized the rooting. And guess what? This is the next permutation. And that is how you find the next permutation without using factorial time or expanding a brute force solution. And so now the time and space complexities are very straightforward. N is the length of the permutation string we start with. So the time complexity is going to be O of N. We're going to scale in a linear fashion as our input gets arbitrarily large. This is because all we do is linear time passes. We're going to do a linear time pass to find the longest decreasing sequence. We're going to do a linear time pass to reverse that sequence. And we're just going to do a constant time swapping. So none of this is going to take us past linear time. For space, we're going to stay constant. So the reason it's constant is we're just going to be using local variables. We're just going to be using pointers. We're not going to be using anything that scales our space as the input gets very large. So these are the time complexities. So if you like this video, hit the like button, subscribe to the channel. I hope this explanation was as clear as possible. This is not one of those questions that scales well to other questions. It's really one of those things where it's a raw case analysis and really understanding the backtracking of permutations to be able to analyze a solution like this. It's not something that is going to apply for many things. So that's all for this one and [Music]

Original Description

Free 5-Day Mini-Course: https://backtobackswe.com Try Our Full Platform: https://backtobackswe.com/pricing 📹 Intuitive Video Explanations 🏃 Run Code As You Learn 💾 Save Progress ❓New Unseen Questions 🔎 Get All Solutions Question: Given a permutation of a sequence, calculate the next permutation in that sequence (if the permutation given is the last one, just return an empty array since it has no next permutation...it is the last permutation). Approach 1 (Brute Force) We can compute all permutations and stop on the permutation right after the permutation given. This can have us generate n! permutations in the worst case (the permutation given is the last one). Approach 2 (Use Intuition & Patterns) Permutation Sequence Example: [0, 1, 2] 1.) [0, 1, 2] 2.) [0, 2, 1] 3.) [1, 0, 2] 4.) [1, 2, 0] 5.) [2, 0, 1] 6.) [2, 1, 0] This approach will use the idea that we notice patterns. Notice how we plant the 0, the 1, then the 2 in the first slot as we go through the sequence. Also, notice how the last element is the array completely reversed. These may not matter but we are just piecing things together right now. Let's formulate a plan. [6, 2, 1, 5, 4, 3, 0] We know to get to this permutation we rooted 6 rooted 2 rooted 1 If you remember back to generating permutations it was all about planting items and then picking from a pool of remaining items. When we plant 1 we have a pool like so [5, 4, 3, 0]. Remember how the last permutation was the original pool reversed? We will look for the longest reversed pool because we know that it is the last permutation for that particular rooting. This is [5, 4, 3, 0] in the example given. This is a maximum suffix after the planted 1. 1 is of interest since this means we have exhausted the possibilities of permutations with 1 rooted where it is since it's suffix following it is strictly decreasing. SO TO GET THE NEXT PERMUTATION WE SWAP 1 AND THE SMALLEST NEXT ELEMENT TO MINIMIZE CHANGE IN TH
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Back To Back SWE · Back To Back SWE · 26 of 60

1 4 Tips To Learn Java Programming As Fast As Possible As A Beginner
4 Tips To Learn Java Programming As Fast As Possible As A Beginner
Back To Back SWE
2 3 Mistakes Beginners Make When First Learning Java and Android Development
3 Mistakes Beginners Make When First Learning Java and Android Development
Back To Back SWE
3 How To Get A Job At Google | The Ultimate Guide To Algorithmic/Coding Interviews
How To Get A Job At Google | The Ultimate Guide To Algorithmic/Coding Interviews
Back To Back SWE
4 The Ultimate Big O Notation Tutorial (Time & Space Complexity For Algorithms)
The Ultimate Big O Notation Tutorial (Time & Space Complexity For Algorithms)
Back To Back SWE
5 Total Occurrences Of K In A Sorted Array (Facebook Software Engineering Interview Question)
Total Occurrences Of K In A Sorted Array (Facebook Software Engineering Interview Question)
Back To Back SWE
6 The N Queens Problem using Backtracking/Recursion - Explained
The N Queens Problem using Backtracking/Recursion - Explained
Back To Back SWE
7 Compute All Mnemonics For A Phone Number (Recursion/Backtracking Problem)
Compute All Mnemonics For A Phone Number (Recursion/Backtracking Problem)
Back To Back SWE
8 How To Reverse A Singly Linked List | The Ultimate Explanation (Iteratively & Recursively)
How To Reverse A Singly Linked List | The Ultimate Explanation (Iteratively & Recursively)
Back To Back SWE
9 Depth First & Breadth First Graph Search - DFS & BFS Graph Searching Algorithms
Depth First & Breadth First Graph Search - DFS & BFS Graph Searching Algorithms
Back To Back SWE
10 The 0/1 Knapsack Problem (Demystifying Dynamic Programming)
The 0/1 Knapsack Problem (Demystifying Dynamic Programming)
Back To Back SWE
11 The Dutch National Flag Problem (The Quicksort "Band-Aid")
The Dutch National Flag Problem (The Quicksort "Band-Aid")
Back To Back SWE
12 Test If A Binary Tree Is Symmetric ("Symmetric Tree" on Leetcode)
Test If A Binary Tree Is Symmetric ("Symmetric Tree" on Leetcode)
Back To Back SWE
13 The IP Address Decomposition Problem - Compute All Valid IP Addresses From Raw IP String
The IP Address Decomposition Problem - Compute All Valid IP Addresses From Raw IP String
Back To Back SWE
14 How To Permute A String - Generate All Permutations Of A String
How To Permute A String - Generate All Permutations Of A String
Back To Back SWE
15 The Balanced Parentheses Problem - Classic Stack Problem ("Valid Parentheses" on Leetcode)
The Balanced Parentheses Problem - Classic Stack Problem ("Valid Parentheses" on Leetcode)
Back To Back SWE
16 Knuth–Morris–Pratt (KMP) Pattern Matching Substring Search -  First Occurrence Of Substring
Knuth–Morris–Pratt (KMP) Pattern Matching Substring Search - First Occurrence Of Substring
Back To Back SWE
17 Implement An LRU Cache - The LRU Cache Eviction Policy ("LRU Cache" on LeetCode)
Implement An LRU Cache - The LRU Cache Eviction Policy ("LRU Cache" on LeetCode)
Back To Back SWE
18 Find The Longest Increasing Subsequence - Dynamic Programming Fundamentals
Find The Longest Increasing Subsequence - Dynamic Programming Fundamentals
Back To Back SWE
19 Generate All Palindromic Decompositions Of A String ("Palindrome Partitioning" on Leetcode)
Generate All Palindromic Decompositions Of A String ("Palindrome Partitioning" on Leetcode)
Back To Back SWE
20 Implement A Sudoku Solver - Sudoku Solving Backtracking Algorithm ("Sudoku Solver" on LeetCode)
Implement A Sudoku Solver - Sudoku Solving Backtracking Algorithm ("Sudoku Solver" on LeetCode)
Back To Back SWE
21 Merge K Sorted Arrays - Min Heap Algorithm ("Merge K Sorted Lists" on LeetCode)
Merge K Sorted Arrays - Min Heap Algorithm ("Merge K Sorted Lists" on LeetCode)
Back To Back SWE
22 Partition To K Equal Sum Subsets From An Array of Integers - The Backtracking Approach
Partition To K Equal Sum Subsets From An Array of Integers - The Backtracking Approach
Back To Back SWE
23 Edit Distance Between 2 Strings - The Levenshtein Distance ("Edit Distance" on LeetCode)
Edit Distance Between 2 Strings - The Levenshtein Distance ("Edit Distance" on LeetCode)
Back To Back SWE
24 Total Ways To Decode A String - Recursive Dynamic Programming Approach ("Decode Ways" on LeetCode)
Total Ways To Decode A String - Recursive Dynamic Programming Approach ("Decode Ways" on LeetCode)
Back To Back SWE
25 The Change Making Problem - Fewest Coins To Make Change Dynamic Programming
The Change Making Problem - Fewest Coins To Make Change Dynamic Programming
Back To Back SWE
Compute The Next Permutation of A Numeric Sequence - Case Analysis ("Next Permutation" on Leetcode)
Compute The Next Permutation of A Numeric Sequence - Case Analysis ("Next Permutation" on Leetcode)
Back To Back SWE
27 Count Total Unique Binary Search Trees - The nth Catalan Number (Dynamic Programming)
Count Total Unique Binary Search Trees - The nth Catalan Number (Dynamic Programming)
Back To Back SWE
28 Generate All Strings With n Matched Parentheses - Backtracking ("Generate Parentheses" on LeetCode)
Generate All Strings With n Matched Parentheses - Backtracking ("Generate Parentheses" on LeetCode)
Back To Back SWE
29 Implement A Max Stack - A Stack With A .max() API (Similar To "Min Stack" on LeetCode)
Implement A Max Stack - A Stack With A .max() API (Similar To "Min Stack" on LeetCode)
Back To Back SWE
30 The Recursive Staircase - Top Down & Bottom Up Dynamic Programming ("Climbing Stairs" on LeetCode)
The Recursive Staircase - Top Down & Bottom Up Dynamic Programming ("Climbing Stairs" on LeetCode)
Back To Back SWE
31 Search A Maze For Any Path - Depth First Search Fundamentals (Similar To "The Maze" on Leetcode)
Search A Maze For Any Path - Depth First Search Fundamentals (Similar To "The Maze" on Leetcode)
Back To Back SWE
32 Total Unique Ways To Make Change - Dynamic Programming ("Coin Change 2" on LeetCode)
Total Unique Ways To Make Change - Dynamic Programming ("Coin Change 2" on LeetCode)
Back To Back SWE
33 Test If A Binary Tree Is Height Balanced ("Balanced Binary Tree" on LeetCode)
Test If A Binary Tree Is Height Balanced ("Balanced Binary Tree" on LeetCode)
Back To Back SWE
34 Find The Second Largest Item - Heap & Tracking Approach (Beginner Big N Interview Question)
Find The Second Largest Item - Heap & Tracking Approach (Beginner Big N Interview Question)
Back To Back SWE
35 Increment An Integer Represented As An Array ("Plus One" on LeetCode)
Increment An Integer Represented As An Array ("Plus One" on LeetCode)
Back To Back SWE
36 Merge 2 Sorted Lists - A Fundamental Merge Sort Subroutine ("Merge Two Sorted Lists" on LeetCode)
Merge 2 Sorted Lists - A Fundamental Merge Sort Subroutine ("Merge Two Sorted Lists" on LeetCode)
Back To Back SWE
37 Clone An Undirected Graph - The Utility of Hashtable Mappings ("Clone Graph" on Leetcode)
Clone An Undirected Graph - The Utility of Hashtable Mappings ("Clone Graph" on Leetcode)
Back To Back SWE
38 Clone A Linked List (With Random Pointers) - Linear Space Solution & Tricky Constant Space Solution
Clone A Linked List (With Random Pointers) - Linear Space Solution & Tricky Constant Space Solution
Back To Back SWE
39 Deeply Understanding Logarithms In Time Complexities & Their Role In Computer Science
Deeply Understanding Logarithms In Time Complexities & Their Role In Computer Science
Back To Back SWE
40 Implement A Binary Heap - An Efficient Implementation of The Priority Queue ADT (Abstract Data Type)
Implement A Binary Heap - An Efficient Implementation of The Priority Queue ADT (Abstract Data Type)
Back To Back SWE
41 Max Contiguous Subarray Sum - Cubic Time To Kadane's Algorithm ("Maximum Subarray" on LeetCode)
Max Contiguous Subarray Sum - Cubic Time To Kadane's Algorithm ("Maximum Subarray" on LeetCode)
Back To Back SWE
42 Binary Tree Bootcamp: Full, Complete, & Perfect Trees. Preorder, Inorder, & Postorder Traversal.
Binary Tree Bootcamp: Full, Complete, & Perfect Trees. Preorder, Inorder, & Postorder Traversal.
Back To Back SWE
43 What Is Asymptotic Analysis? And Why Does It Matter? A Deeper Understanding of Asymptotic Notation.
What Is Asymptotic Analysis? And Why Does It Matter? A Deeper Understanding of Asymptotic Notation.
Back To Back SWE
44 An In-Depth Algorithmic Analysis of Bubble Sort. Best Case, Average Case, & Worst Case.
An In-Depth Algorithmic Analysis of Bubble Sort. Best Case, Average Case, & Worst Case.
Back To Back SWE
45 Maximum Sum Rectangle In A 2D Matrix - Kadane's Algorithm Applications (Dynamic Programming)
Maximum Sum Rectangle In A 2D Matrix - Kadane's Algorithm Applications (Dynamic Programming)
Back To Back SWE
46 A Detailed Algorithmic Analysis of Insertion Sort. Best Case & Worst Case.
A Detailed Algorithmic Analysis of Insertion Sort. Best Case & Worst Case.
Back To Back SWE
47 Binary Tree Level Order Traversal - Drawing The Parallel Between Trees & Graphs
Binary Tree Level Order Traversal - Drawing The Parallel Between Trees & Graphs
Back To Back SWE
48 Implement A Queue Using Stacks - The Queue ADT ("Implement Queue Using Stacks" on LeetCode)
Implement A Queue Using Stacks - The Queue ADT ("Implement Queue Using Stacks" on LeetCode)
Back To Back SWE
49 All Nodes Distance K In A Binary Tree - Performing Bidirectional Search On A Tree Using A Hashtable
All Nodes Distance K In A Binary Tree - Performing Bidirectional Search On A Tree Using A Hashtable
Back To Back SWE
50 Longest Common Subsequence (2 Strings) - Dynamic Programming & Competing Subproblems
Longest Common Subsequence (2 Strings) - Dynamic Programming & Competing Subproblems
Back To Back SWE
51 Egg Dropping Problem: Dynamic Programming Fundamentals & Understanding Subproblem Decomposition
Egg Dropping Problem: Dynamic Programming Fundamentals & Understanding Subproblem Decomposition
Back To Back SWE
52 Minimum Window Substring: Utilizing Two Pointers & Tracking Character Mappings With A Hashtable
Minimum Window Substring: Utilizing Two Pointers & Tracking Character Mappings With A Hashtable
Back To Back SWE
53 Reverse Polish Notation: Types of Mathematical Notations & Using A Stack To Solve RPN Expressions
Reverse Polish Notation: Types of Mathematical Notations & Using A Stack To Solve RPN Expressions
Back To Back SWE
54 Asymptotic Notations 101: Big O, Big Omega, & Theta (Asymptotic Analysis Bootcamp)
Asymptotic Notations 101: Big O, Big Omega, & Theta (Asymptotic Analysis Bootcamp)
Back To Back SWE
55 The Backtracking Blueprint: The Legendary 3 Keys To Backtracking Algorithms
The Backtracking Blueprint: The Legendary 3 Keys To Backtracking Algorithms
Back To Back SWE
56 Fast Multiplication: From Grade-School Multiplication To Karatsuba's Algorithm
Fast Multiplication: From Grade-School Multiplication To Karatsuba's Algorithm
Back To Back SWE
57 Search A 2D Sorted Matrix - Fundamentals of Search Space Reduction
Search A 2D Sorted Matrix - Fundamentals of Search Space Reduction
Back To Back SWE
58 The Quicksort Sorting Algorithm: Pick A Pivot, Partition, & Recurse
The Quicksort Sorting Algorithm: Pick A Pivot, Partition, & Recurse
Back To Back SWE
59 Lowest Common Ancestor Between 2 Binary Tree Nodes (A Recursive Approach)
Lowest Common Ancestor Between 2 Binary Tree Nodes (A Recursive Approach)
Back To Back SWE
60 Sort A K Sorted Array - Investigating Applications of Min/Max Heaps
Sort A K Sorted Array - Investigating Applications of Min/Max Heaps
Back To Back SWE

Related Reads

Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →