├── .gitattributes
├── .github
├── FUNDING.yml
└── workflows
│ └── pages.yml
├── .gitignore
├── .idea
├── .gitignore
├── AceTheJavaCodingInterview.iml
├── aws.xml
├── codeStyles
│ └── codeStyleConfig.xml
├── codestream.xml
├── compiler.xml
├── git_toolbox_prj.xml
├── google-java-format.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jarRepositories.xml
├── misc.xml
├── uiDesigner.xml
├── vcs.xml
└── workspace.xml
├── README.md
├── app
├── build.gradle
└── src
│ ├── main
│ └── java
│ │ └── AceTheJavaCodingInterview
│ │ ├── App.java
│ │ ├── module1_big_o_notation
│ │ ├── BigONestedLoopWithAddition.java
│ │ ├── BigONestedLoopWithMultiplication.java
│ │ ├── BigONestedLoopWithSubtraction.java
│ │ ├── _big_o_notation_formulae.md
│ │ └── problem_sets
│ │ │ ├── ProblemSet1.java
│ │ │ └── ProblemSet2.java
│ │ └── module2_data_structures
│ │ ├── ClassTemplate.java
│ │ ├── arrays
│ │ ├── FindMaximumInSlidingWindow.java
│ │ ├── FindTheSmallestCommonNumber.java
│ │ ├── MaximumSumSubarrayOfSizeK.java
│ │ ├── MergeAnArrayWithOverlappingIntervals.java
│ │ ├── OneDimensionalArrays.java
│ │ ├── PairWithTargetSum.java
│ │ ├── Permutations.java
│ │ ├── SmallestSubarrayWithAGreaterSum.java
│ │ ├── SquaringASortedArray.java
│ │ ├── SubArraysWithProductLessThanTarget.java
│ │ ├── Subset.java
│ │ ├── SubsetsWithDuplicates.java
│ │ ├── TripletSumCloseToTarget.java
│ │ ├── TripletSumToZero.java
│ │ ├── TripletsWithSmallerSum_ReturnCount.java
│ │ ├── TripletsWithSmallerSum_ReturnList.java
│ │ ├── TwoDimensionalArrays.java
│ │ ├── _arrays.md
│ │ ├── binary_search
│ │ │ ├── BinarySearchOnSortedArray_Iterative.java
│ │ │ ├── BinarySearchOnSortedArray_Recursive.java
│ │ │ ├── BitonicArrayMaximum.java
│ │ │ ├── FindLowOrHighIndexOfAnElementInSortedArray.java
│ │ │ ├── MoveAllZerosToTheBeginningOfTheArray.java
│ │ │ ├── OrderAgnosticBinarySearch.java
│ │ │ ├── SearchRotatedArray_Iteratively.java
│ │ │ ├── SearchRotatedArray_Recursive.java
│ │ │ └── StockBuySellToMaximizeProfit.java
│ │ ├── challenges
│ │ │ ├── CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_1.java
│ │ │ ├── CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_2.java
│ │ │ ├── CH11_FindTheSumOfMaximumSumSubarray.java
│ │ │ ├── CH1_RemoveEvenFromArray.java
│ │ │ ├── CH2_MergeTwoSortedArrays.java
│ │ │ ├── CH3_FindTwoNoAddingUpToN_Sol_1.java
│ │ │ ├── CH3_FindTwoNoAddingUpToN_Sol_2.java
│ │ │ ├── CH4_ArrayOFProductsOfAllElementsExceptItself.java
│ │ │ ├── CH5_FindMinimumValueInArray.java
│ │ │ ├── CH6_FindFirstNonRepeatingIntegerInArray.java
│ │ │ ├── CH7_FindSecondMaximumValueInArray_Sol_1.java
│ │ │ ├── CH7_FindSecondMaximumValueInArray_Sol_2.java
│ │ │ ├── CH8_RightRotateTheArrayByOneIndex.java
│ │ │ ├── CH9_ReArrangePositiveAndNegativeValues_SOL_1.java
│ │ │ └── CH9_ReArrangePositiveAndNegativeValues_SOL_2.java
│ │ └── sorting
│ │ │ ├── CyclicSortEasy.java
│ │ │ └── QuicksortAlgorithm.java
│ │ ├── hash_tables
│ │ ├── PairWithTargetSum.java
│ │ └── _hash_tables.md
│ │ ├── stacks_and_queues
│ │ └── _stacks_and_queues.md
│ │ ├── tuples
│ │ ├── Interval.java
│ │ ├── Tuple.java
│ │ └── _tuples.md
│ │ └── utils
│ │ └── DataStructuresUtils.java
│ └── test
│ └── java
│ └── AceTheJavaCodingInterview
│ └── AppTest.java
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitattributes:
--------------------------------------------------------------------------------
1 | #
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | #
4 | # These are explicitly windows files and should use crlf
5 | *.bat text eol=crlf
6 |
7 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: david-kariuki # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: davidkariuki # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/.github/workflows/pages.yml:
--------------------------------------------------------------------------------
1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages
2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["master"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow one concurrent deployment
19 | concurrency:
20 | group: "pages"
21 | cancel-in-progress: true
22 |
23 | jobs:
24 | # Build job
25 | build:
26 | runs-on: ubuntu-latest
27 | steps:
28 |
29 | - name: Checkout
30 | uses: actions/checkout@v3
31 | - name: Setup Pages
32 | uses: actions/configure-pages@v1
33 | - name: Build with Jekyll
34 | uses: actions/jekyll-build-pages@v1
35 | with:
36 | source: ./
37 | destination: ./_site
38 | - name: Upload artifact
39 | uses: actions/upload-pages-artifact@v1
40 | - name: Close Stale Issues
41 | uses: actions/stale@v5.1.1
42 | - name: Setup Node.js environment
43 | uses: actions/setup-node@v3.4.1
44 | - name: Setup Go environment
45 | uses: actions/setup-go@v3.3.0
46 | - name: SonarCloud Scan
47 | # You may pin to the exact commit or the version.
48 | # uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049
49 | uses: SonarSource/sonarcloud-github-action@v1.6
50 | - name: HashiCorp's Link Checker
51 | # You may pin to the exact commit or the version.
52 | # uses: hashicorp/gh-action-check-broken-links@9da9ec2d83f88fe981a856c3f03aca64e68af90c
53 | uses: hashicorp/gh-action-check-broken-links@v1
54 | - name: Cache
55 | uses: actions/cache@v3.0.8
56 |
57 |
58 | # Deployment job
59 | deploy:
60 | environment:
61 | name: github-pages
62 | url: ${{ steps.deployment.outputs.page_url }}
63 | runs-on: ubuntu-latest
64 | needs: build
65 | steps:
66 | - name: Deploy to GitHub Pages
67 | id: deployment
68 | uses: actions/deploy-pages@v1
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore Gradle project-specific cache directory
2 | .gradle
3 |
4 | # Ignore Gradle build output directory
5 | build
6 | /.idea/uiDesigner.xml
7 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # CodeStream ignored files
7 | /../../AceTheJavaCodingInterview\.idea/codestream.xml
8 | # Datasource local storage ignored files
9 | /dataSources/
10 | /dataSources.local.xml
11 | # Zeppelin ignored files
12 | /ZeppelinRemoteNotebooks/
13 |
--------------------------------------------------------------------------------
/.idea/AceTheJavaCodingInterview.iml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 
7 | 
8 | 
9 | 
10 | 
11 | 
12 |
13 |
14 | # Project Contents
15 |
16 |
17 |
18 |
19 | ## 1. Complexity Problems
20 | - Introduction to Asymptotic Analysis and Big O
21 | - Challenge 1: Big (O) of Nested Loop with Addition
22 | - Challenge 2: Big (O) of Nested Loop with Subtraction
23 | - Challenge 3: Big O of Nested Loop with Multiplication
24 | - Challenge 4: Nested Loop with Multiplication (Basic)
25 | - Challenge 5: Nested Loop with Multiplication (Intermediate)
26 | - Challenge 6: Nested Loop with Multiplication (Advanced)
27 | - Challenge 7: Nested Loop with Multiplication (Pro)
28 | - Problem Sets
29 | - Complexity Interview Questions
30 | - Cheat Sheet
31 |
32 |
33 | ## 2. DATA STRUCTURES
34 |
35 | a. ARRAYS
36 |
37 | . Two Dimensional Arrays.
38 | . Challenge 1: Remove Even Integers from an Array
39 | . Challenge 2: Merge Two Sorted Arrays
40 | . Challenge 3: Find Two Numbers that Add up to "n"
41 | . Challenge 4: Array of Products of All Elements Except Itself
42 | . Challenge 5: Find Minimum Value in Array
43 | . Challenge 6: First Non-Repeating Integer in an Array
44 | . Challenge 7: Find Second Maximum Value in an Array
45 | . Challenge 8: Right Rotate the Array by One Index
46 | . Challenge 9: Re-arrange Positive & Negative Values
47 | . Challenge 10: Rearrange Sorted Array in Max/Min Form
48 | . Challenge 11: Find the Sum of Maximum Sum Subarray
49 | . Implement Binary Search on a Sorted Array
50 | . Find Maximum in Sliding Window
51 | . Search a Rotated Array
52 | . Find the Smallest Common Number
53 | . Find Low/High Index of an Element in a Sorted Array
54 | . Move All Zeros to the Beginning of the Array
55 | . Stock Buy Sell to Maximize Profit
56 | . Merge an Array With Overlapping Intervals
57 | . Sort an Array Using Quicksort Algorithm
58 | . Cyclic Sort (easy)
59 | . Maximum Sum Subarray of Size K (easy)
60 | . Smallest Subarray With a Greater Sum (easy)
61 | . Squaring a Sorted Array (easy)
62 | . Subset (easy)
63 | . Subsets With Duplicates (easy)
64 | . Order-agnostic Binary Search (easy)
65 | . Bitonic Array Maximum (easy)
66 | .
67 |
68 |
69 | b. LINKED LISTS
70 |
71 | . Introduction to Linked Lists
72 | . Basic Linked List Operations
73 | . Insertion in a Singly Linked List
74 | . Challenge 1: Insertion in a Singly Linked List (insert at End)
75 | . Solution Review: Insertion in a Singly Linked List(insert at End)
76 | . Challenge 2: Search in Singly Linked List
77 | . Solution Review: Search in a Singly Linked List
78 | . Challenge 3: Deletion in Singly Linked List(Delete by Value)
79 | . Solution Review: Deletion in Singly Linked List
80 | . Linked Lists vs. Arrays
81 | . What is a Doubly Linked List (DLL)?
82 | . Linked List with Tail
83 | . Challenge 4: Find the Length of a Linked List
84 | . Solution Review: Find the Length of a Linked List
85 | . Challenge 5: Reverse a Linked List
86 | . Solution Review: Reverse a Linked List
87 | . Challenge 6: Detect Loop in a Linked List
88 | . Solution Review: Detect Loop in a Linked List
89 | . Challenge 7: Find the Middle Node of a Linked List
90 | . Solution Review: Find the Middle Node of a Linked List
91 | . Challenge 8: Remove Duplicates from a Linked List
92 | . Solution Review: Remove Duplicate from a Linked List
93 | . Challenge 9: Union and Intersection of Lists
94 | . Solution Review: Union & Intersection of Lists
95 | . Challenge 10: Return the Nth node from End
96 | . Solution Review: Return the Nth node from End
97 | . Challenge 11: Find if Doubly Linked-list is a Palindrome
98 | . Solution: Find if a Doubly Linked-list is a Palindrome
99 | . Implementation of Linked List
100 | . Intersection Point of Two Lists
101 | . Rotate a Linked List
102 | . Reverse Alternative K Node in a Singly Linked List
103 | . Add Two Integers Represented by Linked Lists
104 | . Reverse a Sub-list (medium)
105 | . Reverse every K-element Sub-list (medium)
106 | . Merge K Sorted Lists (medium)
107 | . Kth Smallest Number in M Sorted Lists (medium)
108 | . Linked list Interview Questions
109 |
110 |
111 | c. STRINGS
112 |
113 | . String: Common Methods & Operations
114 | . Reverse Words in a Sentence
115 | . Remove Duplicates from a String
116 | . Remove White Spaces from a String
117 | . Word Break Problem
118 | . XML to Tree
119 | . Find all Palindrome Substrings
120 | . Regular Expression Matching in String
121 | . Longest Palindromic Substring
122 | . Longest Palindromic Subsequence
123 | . Count of Palindromic Substrings
124 | . Minimum Deletions in a String to make it a Palindrome
125 | . Palindromic Partitioning
126 | . Longest Common Substring
127 | . Longest Common Subsequence
128 | . Minimum Deletions & Insertions to Transform a String into another
129 | . Fruits into Baskets (medium)
130 | . Longest Substring with maximum K Distinct Characters (medium)
131 | . String Permutations by changing case (medium)
132 | . Balanced Parentheses (hard)
133 | . Unique Generalized Abbreviations (hard)
134 | . Longest Substring with Distinct Characters (hard)
135 | . Longest Substring with Same Letters after Replacement (hard)
136 | . Boggle
137 | . Generate all Combinations of Balanced Parentheses
138 |
139 |
140 | d. STACKS and QUEUES
141 |
142 | . Introduction to Stacks & Queues
143 | . Stack (Implementation)
144 | . Queue (Implementation)
145 | . Implement Queue Using Stacks
146 | . Implement Stack Using Queues
147 | . Challenge 1: Generate Binary Numbers from 1 to n using a Queue
148 | . Solution Review: Generate Binary Numbers from 1 to n using Queue
149 | . Challenge 2: Implement Two Stacks using one Array
150 | . Solution Review: Implement Two Stacks using one Array
151 | . Challenge 3: Reversing the First k Elements of a Queue
152 | . Solution Review: Reversing the First k Elements of a Queue
153 | . Challenge 4: Implement Queue using Stack
154 | . Solution Review: Implement Queue using Stack
155 | . Challenge 5: Sort the Values in a Stack
156 | . Solution Review: Sort the Values in a Stack
157 | . Challenge 6: Evaluate Postfix Expressions using Stacks
158 | . Solution Review: Evaluate Postfix Expressions using Stacks
159 | . Challenge 7: Next Greater Element using Stack
160 | . Solution Review: Next Greater Element using Stack
161 | . Challenge 8: Solve a Celebrity Problem using a Stack
162 | . Solution Review: Solve a Celebrity Problem using a Stack
163 | . Challenge 9: Check for Balanced Parentheses using a Stack
164 | . Solution Review: Check for Balanced Parentheses using a Stack
165 | . Challenge 10: Create Stack where min() gives minimum in O(1)
166 | . Solution Review: Create Stack where min() gives minimum in O(1)
167 | . Stack/Queue Interview Questions
168 |
169 |
170 | e. TREES
171 |
172 | . Introduction to Trees
173 | . Implementation of Binary Tree
174 | . Check if Two Binary Trees are Identical
175 | . Write an In-Order Iterator for a Binary Tree
176 | . Iterative In-order Traversal of Binary Tree
177 | . In-order Successor of Binary Search Tree
178 | . In-order Successor Binary Search Tree With Parent Pointers
179 | . Level Order Traversal of Binary Tree
180 | . Is a Binary Search Tree Valid?
181 | . Convert Binary Tree to Doubly Linked List
182 | . Print Tree Perimeter
183 | . Connect Same Level Siblings of a Binary Tree
184 | . Connect All Siblings of a Binary Tree
185 | . Serialize/Deserialize Binary Tree
186 | . Nth Highest Number in Binary Search Tree
187 | . Mirror Binary Tree Nodes
188 | . Delete Zero Sum Sub-Trees
189 | . Convert N-ary Tree to Binary Tree
190 |
191 |
192 | f. TRIE
193 |
194 | . Introduction to Tries
195 | . Insertion in a Trie
196 | . Search in a Trie
197 | . Deletion in a Trie
198 | . The Structure of a Trie
199 | . Challenge 1: Total Number of Words in a Trie
200 | . Solution Review: Total Number of Words in a Trie
201 | . Challenge 2: Find All of the Words in a Trie
202 | . Solution Review: Find All of the Words in a Trie
203 | . Challenge 3: Sort the Elements of an Array using a Trie.
204 | . Solution Review: Sort the Elements of an Array using a Trie.
205 | . Challenge 4: Word Formation from a Given Dictionary using a Trie
206 | . Solution Review: Word Formation from Given Dictionary using Trie
207 | . Trie Interview Questions
208 |
209 |
210 | g. HEAPS
211 |
212 | . Introduction to Heaps
213 | . Heap Representation in Arrays
214 | . Max Heap: Introduction
215 | . Max Heap (Implementation)
216 | . Min Heap: An Introduction
217 | . Min Heap (Implementation)
218 | . Challenge 1: Convert a Max-Heap to a Min-Heap
219 | . Solution Review: Convert a Max-Heap to a Min-Heap
220 | . Challenge 2: Find the k Smallest Elements in an Array
221 | . Solution Review: Find the k Smallest Elements in an Array
222 | . Challenge 3: Find the k Largest Elements in an Array
223 | . Solution Review: Find the k Largest Elements in an Array
224 | . Heap Interview Questions
225 |
226 |
227 | h. HASH TABLES
228 |
229 | . Introduction to Hash Tables
230 | . Trie vs Hash Table
231 | . HashMap vs HashSet
232 | . Challenge 1: Find whether an array is a subset of another array
233 | . Solution Review: Find whether an array is a subset of another array
234 | . Challenge 2: Check if the given arrays are disjoint
235 | . Solution Review: Check if the given arrays are disjoint
236 | . Challenge 3: Find symmetric pairs in an Array
237 | . Solution Review: Find symmetric pairs in an Array
238 | . Challenge 4: Trace the complete path of a journey
239 | . Solution Review: Trace the complete path of a journey
240 | . Challenge 5: Find two pairs in an Array such that a+b = c+d
241 | . Solution Review: Find two pairs in an Array such that a+b = c+d
242 | . Challenge 6: Find If a Subarray with a Sum Equal to 0 Exists
243 | . Solution Review: Find if a subarray with a sum equal to 0 exists.
244 | . Challenge 7: First Non-Repeating Integer in an Array
245 | . Solution Review: First Non-Repeating Integer in an Array
246 | . Challenge 8: Remove Duplicate from a Linked List using Hashing
247 | . Solution Review: Remove Duplicate from Linked List using Hashing
248 | . Challenge 9: Union and Intersection of Lists using Hashing
249 | . Solution Review: Union and Intersection of Lists using Hashing
250 | . Challenge 10: Find Two Numbers that Add up to "n"
251 | . Solution Review: Find Two Numbers that Add up to "n"
252 | . Hashing Interview Questions
253 |
254 |
255 | i. GRAPHS
256 |
257 | . Introduction to Graphs
258 | . Graph Implementation
259 | . What is a Bipartite Graph?
260 | . Challenge 1: Implement Breadth First Search
261 | . Solution Review: Implement Breadth First Search
262 | . Challenge 2: Implement Depth First Search
263 | . Solution Review: Implement Depth First Search
264 | . Challenge 3: Cycle Detection in a Directed Graph
265 | . Solution Review: Cycle Detection in a Directed Graph
266 | . Challenge 4: Find "Mother Vertex" in a Directed Graph
267 | . Solution Review: Find "Mother Vertex" in a Directed Graph
268 | . Challenge 5: Count the Number of Edges in an Undirected Graph
269 | . Solution Review: Count the number of Edges in an Undirected Graph
270 | . Challenge 6: Check if a Path Exists Between Two Vertices
271 | . Solution Review: Check if a Path Exists Between Two Vertices
272 | . Challenge 7: Check if a Directed Graph is Tree or not
273 | . Solution Review: Check if a Directed Graph is Tree or not
274 | . Challenge 8: Find Length of Shortest Path between Two Vertices
275 | . Solution Review: Find the Shortest Path between Two Vertices
276 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * This generated file contains a sample Java application project to get you started.
5 | * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
6 | * User Manual available at https://docs.gradle.org/7.4/userguide/building_java_projects.html
7 | * This project uses @Incubating APIs which are subject to change.
8 | */
9 |
10 | plugins {
11 | // Apply the application plugin to add support for building a CLI application in Java.
12 | id 'application'
13 | }
14 |
15 | repositories {
16 | // Use Maven Central for resolving dependencies.
17 | mavenCentral()
18 | }
19 |
20 | dependencies {
21 | // This dependency is used by the application.
22 | implementation 'com.google.guava:guava:30.1.1-jre'
23 | }
24 |
25 | testing {
26 | suites {
27 | // Configure the built-in test suite
28 | test {
29 | // Use JUnit Jupiter test framework
30 | useJUnitJupiter('5.8.1')
31 | }
32 | }
33 | }
34 |
35 | application {
36 | // Define the main class for the application.
37 | mainClass = 'AceTheJavaCodingInterview.App'
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/App.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This Java source file was generated by the Gradle 'init' task.
3 | */
4 | package AceTheJavaCodingInterview;
5 |
6 | public class App {
7 | public String getGreeting() {
8 | return "Hello World!";
9 | }
10 |
11 | public static void main(String[] args) {
12 | System.out.println(new App().getGreeting());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/BigONestedLoopWithAddition.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Big (O) of Nested Loop With Addition
3 | * Compute the Big O complexity of the code snippet given below.
4 | *
5 | * @authr David Kariuki
6 | * @since 10/8/2022
7 | */
8 |
9 | package AceTheJavaCodingInterview.module1_big_o_notation;
10 |
11 | public class BigONestedLoopWithAddition {
12 |
13 | public static void main(String[] args) {
14 | int n = 10; // 1 step - Initializing a variable is a basic operation that costs one unit.
15 | int sum = 0; // 1 step - Initializing a variable is a basic operation that costs one unit.
16 | double pie = 3.14; // 1 step - Initializing a variable is a basic operation that costs one unit.
17 |
18 | /*
19 | * int var = 0; - Initializing a variable is a basic operation that costs one unit.
20 | *
21 | * var < n;
22 | * This condition executes in steps of 3,i.e., initially var = 0, and hence var is less than n.
23 | * In the next step var is 3 --> still less than n. Then var = 6 -> still less than n var = 9 --> still less
24 | * than n. But when var = 12, it is greater than n,loop breaks here.From this example notice that the loop
25 | * runs n/3 times and 1 time extra this condition is executed for breaking the loop.
26 | */
27 | for (int var = 0; var < n; var = var + 3) { // n/3 steps
28 |
29 | // The outer-loop runs n/3 times so the print statement is executed n/3 times.
30 | System.out.println("\nFor loop at " + var + " Pie: " + pie);
31 |
32 | /*
33 | * int j = 0 itself is executed in 1 unit of time.
34 | * However, this statement is executed n/3 times due to outer for-loop.
35 | *
36 | * j < n;
37 | * The outer loop runs n/3 times.The statement j < n executes in steps of 2 due to the inner loop.
38 | * In each iteration of the inner loop 2 is added to j. Therefore, this statement runs (n/2 + 1) times due
39 | * to inner loop,and in turn executes n/3(n/2 + 1) due to outer loop.
40 | */
41 | for (int j = 0; j < n; j = j + 2) { // (n/3 * n/2) steps
42 |
43 | // (n/3 * n/2) steps - The outer loop runs n/3 times, and the inner loop runs n/2 times.Therefore,
44 | // sum++ is executed n/3(n/2) times.
45 | sum++;
46 |
47 | System.out.println("When var : " + var + " and j : " + j + " Sum : " + sum + " and n " + n); //
48 | // (n/3 * n/2) steps
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/BigONestedLoopWithMultiplication.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Big (O) of Nested Loop With Multiplication
3 | * Compute the Big O complexity of the code snippet given below.
4 | *
5 | * @authr David Kariuki
6 | * @since 12/8/2022
7 | */
8 |
9 | package AceTheJavaCodingInterview.module1_big_o_notation;
10 |
11 | @SuppressWarnings("ALL")
12 | public class BigONestedLoopWithMultiplication {
13 |
14 | public static void main(String[] args) {
15 | withMultiplicationBasic1();
16 | withMultiplicationBasic2();
17 | withMultiplicationIntermediate();
18 | withMultiplicationAdvanced();
19 | }
20 |
21 | /**
22 | * @note Nested Loop with Multiplication (Basic) 1
23 | * Compute the Big O complexity of the code snippet given below.
24 | */
25 | public static void withMultiplicationBasic1() {
26 |
27 | System.out.println("\n\n Starting Simple");
28 |
29 | int n = 16; // O(time complexity of the called function)
30 | int sum = 0; // O(1)
31 | double pie = 3.14; // O(1)
32 | int var = 1; // O(1
33 |
34 |
35 | while (var < n) { // O(log n)
36 |
37 | System.out.println("Pie: " + pie); // O(log n)
38 |
39 | for (int j = 0; // O(log n)
40 | j < var; j++) { // 2n
41 | sum++; // (2n-1)
42 | }
43 | var *= 2; // O(log n)
44 | } //end of while loop
45 |
46 | System.out.println("Sum: " + sum); //O(1)
47 |
48 | // Answer -> O(n)
49 | }
50 |
51 | /**
52 | * @note Nested Loop with Multiplication (Basic) 2
53 | * Compute the Big O complexity of the code snippet given below.
54 | */
55 | public static void withMultiplicationBasic2() {
56 |
57 | System.out.println("\n\n Starting Basic");
58 |
59 | int n = 10; // O(time complexity of the called function)
60 | int sum = 0; //O(1)
61 | double pie = 3.14; //O(1)
62 | int var = 1;
63 |
64 |
65 | while (var < n) { // O(log3 n)
66 | System.out.println("Pie: " + pie); // O(log3 n)
67 |
68 | for (int j = 1; // O(log3 n)
69 | // The inner loop is executed n/2 times. This condition is however, checked 1 more time for breaking
70 | // the loop.The outer loop is executed log3(n) times. Therefore, this statement is executed
71 | // log3(n) x (n/2 + 1) times
72 | j < n;
73 |
74 | // The inner loop is executed n/2 times. The outer loop is executed log3(n) times. Therefore, this
75 | // statement is executed log3(n) x (n/2) times
76 | j = j + 2) { // O((log3 n)* (n/2))
77 |
78 | sum++; // O((log3 n)* (n/2) * 2)
79 | }
80 | var *= 3; // O(log3 n)
81 | } //end of while loop
82 | System.out.println("Sum: " + sum); //O(1)
83 |
84 | // Answer -> O(nlog2(n))
85 | }
86 |
87 | /**
88 | * @note Nested Loop with Multiplication (Intermediate)
89 | * Compute the Big O complexity of the code snippet given below.
90 | */
91 | public static void withMultiplicationIntermediate() {
92 |
93 | System.out.println("\n\n Starting Intermediate 1");
94 |
95 | int n = 10; //O(1)
96 | int sum = 0; //O(1)
97 | int j = 1; //O(1)
98 | double pie = 3.14; //O(1)
99 |
100 | //O(?)
101 | for (
102 | int var = 1; // O(1)
103 | var < n; // n/3 + 1
104 | var += 3 // n/3
105 | ) {
106 |
107 | System.out.println("Pie: " + pie); // n/3
108 | j = 1; // n/3
109 | while (j < n) { //O(?)
110 | sum += 1; // (log_3(n) + 1 ) * n/3
111 | j *= 3; // log_3(n) * n/3
112 | }
113 | }
114 |
115 | System.out.println("Sum: " + sum); //O(1)
116 |
117 | // Answer -> O(nlog(n))
118 | }
119 |
120 | /**
121 | * @note Nested Loop with Multiplication (Advanced)
122 | * Compute the Big O complexity of the code snippet given below.
123 | */
124 | public static void withMultiplicationAdvanced() {
125 | int n = 10; //O(1)
126 | int sum = 0; //O(1)
127 | double pie = 3.14; //O(1)
128 |
129 | for (int var = 0; var < n; var++) { //O(n)
130 | int j = 1; //O(n)
131 | System.out.println("Pie: " + pie); //O(n)
132 | while(j < var) { // O((n) * (log2 var))
133 | sum += 1; // O((n) * (log2 var))
134 | j *= 2; // O((n) * (log2 var))
135 | }
136 | }
137 |
138 | System.out.println("Sum: " + sum); //O(1)
139 |
140 | // Answer -> O(nlog2(n))
141 | }
142 |
143 | /**
144 | * @note Nested Loop with Multiplication (Pro)
145 | * Compute the Big O complexity of the code snippet given below.
146 | */
147 | public static void withMultiplicationPro() {
148 |
149 | int n = 10; // O(1)
150 | int sum = 0; // O(1)
151 | int j = 1; // O(1)
152 | double pie = 3.14; // O(1)
153 |
154 | for (int var = 0; var < n; var++) { // 0(n)
155 |
156 | System.out.println("Pie: " + pie); // 0(n)
157 | while(j < var) { // 0(n)
158 | sum += 1; // 0(n)
159 | j *= 2; // 0(n)
160 | }
161 | }
162 |
163 | System.out.println("Sum: " + sum); // O(1)
164 |
165 | // Answer O(n)
166 | }
167 | }
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/BigONestedLoopWithSubtraction.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Big (O) of Nested Loop With Subtraction
3 | * Compute the Big O complexity of the code snippet given below.
4 | *
5 | * @authr David Kariuki
6 | * @since 11/8/2022
7 | */
8 |
9 | package AceTheJavaCodingInterview.module1_big_o_notation;
10 |
11 | public class BigONestedLoopWithSubtraction {
12 |
13 | public static void main(String[] args) {
14 | int n = 10; // O(time complexity of the called function)
15 | int sum = 0; //O(1)
16 | double pie = 3.14; //O(1)
17 |
18 | for (int var = n; var >= 1; var = var - 3) { // O(n/3)
19 | System.out.println("Pie: " + pie); // O(n/3)
20 |
21 | /*
22 | * j >= 0 is executed n + 2 times due to the inner loop. For example if n = 10.
23 | * Then j can have values10, 9, 8, ..., 2, 1, 0. This means that j >= 0 will execute n + 1times
24 | * successfully and another +1 for the loop breaking condition. Total n + 2However, due to the outer loop
25 | * this statement is executed a further n/3 times.Therefore, running time of this statement is n/3(n + 2).
26 | * */
27 | for (int j = n; j >= 0; j = j - 1) { // O((n/3)*(n+1))
28 | sum++; // O((n/3)*(n+1))
29 | }
30 | } //end of outer for loop
31 | System.out.println("Sum: " + sum);//O(1)
32 | } //end of main
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/_big_o_notation_formulae.md:
--------------------------------------------------------------------------------
1 | # Saved concepts and formulae
2 |
3 | ## Big O Notation
4 |
5 |
1. A function `f(n)`, is considered `O(g(n))` (read as big oh of `g(n)`) if there exists some positive real constant `c` and an integer `n_0 > 0`, such that the following inequality holds for all n >= n_0
6 | `f(n) <= cg(n)`
7 |
8 |
2. People tend to write `f(n) = O(g(n))`, which isn’t technically accurate. A lot of functions can satisfy the `O(g(n))` conditions. Therefore, `O(g(n))` is a set of functions, and it is okay to say that `f(n)` belongs to `O(g(n))`.
9 |
10 |
3. `f(n)` will grow no faster than a constant multiple of `g(n)`. Put yet another way, the rate of growth of `f(n)` is within constant factors of that of `g(n)`.
11 |
12 |
4. Suppose algorithms `A` and `B` have running time of `O(n)` and `O(n^2)`, respectively. For sufficiently large input sizes, algorithm `A` will run faster than algorithm `B`. That does not mean that algorithm `A` will always run faster than algorithm `B`.
13 | Algorithm A and B both have running time `O(n)`. The execution time for these algorithms for very large input sizes, will be within constant factors of each other. For all practical purposes, they are considered equally good.
14 |
15 |
5. Simplified asymptotic analysis
16 | Once we have obtained the time complexity of an algorithm by counting the number of primitive operations, we can arrive at the Big O notation for the algorithm simply by:
17 |
18 | - Dropping the multiplicative constants with all terms.
19 | - Dropping all but the highest order term.
20 | - Therefore, `n^2 + 2n + 1` is `O(n^2)` while `n^5 + 4n^3 + 2n + 43` is `O(n^5)`.
21 |
22 | The constant coefficients have become insignificant in the Big O notation. Recall that these constants represent the number of primitive operations on a given line of code. This means that, while analyzing code, counting a line of code
23 | as contributing 4 primitive operations is as good as counting it as 1 primitive operation. What matters is correctly counting the number of times each line of code is repeated.
24 |
25 |
6. A comparison of some common functions
26 | It is easy to work with simple polynomials in n, but when the time complexity involves other types of functions like log(), you may find it hard to identify the “highest order term”. The following table lists some commonly encountered
27 | functions in ascending order of rate of growth. Any function can be given as a Big O of any other function that appears later in this table.
28 |
29 | | # | Name | Function |
30 | |-|-|-|
31 | | 1. | Any constant | Constant |
32 | | 2. | logn | Logarithmic |
33 | | 3. | $${log^2n}$$ | Log-square |
34 | | 4. | $$\sqrt{n}$$ | Root-n |
35 | | 5. | n | Linear |
36 | | 6. | nlogn | Linearithmic |
37 | | 7. | $${n^2}$$ | Quadratic |
38 | | 8. | $${n^3}$$ | Cubic |
39 | | 9. | $${n^4}$$ | Quartic |
40 | | 10. | $${2^n}$$ | Exponential |
41 | | 11. | $${e^n}$$ | Exponential |
42 | | 12. | n! | n-Factorial |
43 | ||||
44 |
45 |
7. General Tips
46 |
47 | - Every time a list or array gets iterated over `c×length` times, it is most likely in `O(n)` time.
48 | - When you see a problem where the number of elements in the problem space gets halved each time, it will most probably be in `O(log n)` runtime.
49 | - Whenever you have a single nested loop, the problem is most likely in quadratic time. `O(n2)`.
50 | - A loop statement that multiplies/divides the loop variable by a constant takes log_k(n) time because the loop runs that many times.
51 | - We don’t always add the time complexity of the inner loop. It depends. If the inner loop depends on the outer loop, then the complexity is added, and if the inner loop does not depend on the outer loop, then we multiply it.
52 | - `log(a)` + `log(b)` = `log(ab)`
53 | - An algorithm is said to be constant time (also written as `O(1)}` time) if the value of `T(n)` is bounded by a value that does not depend on the size of the input. For example, accessing any single element in an array takes constant time as only one operation has to be performed to locate it. In a similar manner, finding the minimal value in an array sorted in ascending order; it is the first element. However, finding the minimal value in an unordered array is not a constant time operation as scanning over each element in the array is needed in order to determine the minimal value. Hence it is a linear time operation, taking {\textstyle O(n)}{\textstyle O(n)} time. If the number of elements is known in advance and does not change, however, such an algorithm can still be said to run in constant time.
54 | - An algorithm is said to take logarithmic time when `T(n) =O(log n)`. Since `log_a(n)` `log_b(n)` are related by a constant multiplier, and such a multiplier is irrelevant to `big O` classification, the standard usage for logarithmic-time algorithms is `O(log n)` regardless of the base of the logarithm appearing in the expression of T.
55 | Algorithms taking logarithmic time are commonly found in operations on binary trees or when using binary search.
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/problem_sets/ProblemSet1.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Problem set 1
3 | * @author David Kariuki
4 | * @since 14/8/2022
5 | */
6 |
7 | package AceTheJavaCodingInterview.module1_big_o_notation.problem_sets;
8 |
9 | @SuppressWarnings("unused")
10 | public class ProblemSet1 {
11 |
12 | /**
13 | * Following is another implementation of insertion sort. If we feed an already sorted array to the following
14 | * snippet will the algorithm execute a linear number of instructions? Insertion sort’s best-case running time
15 | * is linear (think running a single loop) and not quadratic.
16 | */
17 | public void sort(int[] input) {
18 |
19 | for (int i = 1; i < input.length; i++) {
20 | int key = input[i];
21 | for (int j = i - 1; j >= 0; j--) {
22 | if (input[j] > key) {
23 | int tmp = input[j];
24 | input[j] = key;
25 | input[j + 1] = tmp;
26 | }
27 | }
28 | }
29 |
30 | /*
31 | * Answer - No
32 | *
33 | * The algorithm represents insertion sort. However, the way the code is written, there’s no short-circuiting
34 | * for the nested loop when the values are already sorted so even in the best case, i.e. when the array is
35 | * sorted the inner loops run from the start of the array to the end. Unlike the implementation of insertion
36 | * sort in the lesson, the short-circuiting would never make the inner loop run when the input array is already
37 | * sorted. The best-case time would be linear and not quadratic. However, for the above snippet, the best case
38 | * would still be quadratic. The point to drive home is to exercise caution as slight implementation changes
39 | * can change complexities for the same algorithm.
40 | */
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module1_big_o_notation/problem_sets/ProblemSet2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Problem set 2
3 | * @author David Kariuki
4 | * @since 14/8/2022
5 | */
6 |
7 | package AceTheJavaCodingInterview.module1_big_o_notation.problem_sets;
8 |
9 |
10 | /**
11 | *
12 | * @note Question 1 13 | * Suppose your friend discovers a new algorithm and in his excitement tells you that his algorithm has a lower 14 | * bound of O(n2). Can you explain why your friend's statement makes no sense? 15 | * 16 | *
17 | * Answer 18 | * Big O notation denotes an upper bound but is silent about the lower bound. Treat it like a cap on the worst 19 | * that can happen. So when someone says that an algorithm has a lower bound of O(n2) that translates into saying 20 | * the lower bound can at worst be quadratic in complexity. By definition, the lower bound is the best an algorithm 21 | * can perform. Combine the two statements and your friend is saying the algorithm he found in the best case can 22 | * perform in quadratic time or better. It can also perform in linear time or constant time, we just don't know. 23 | * So your friend is effectively not telling you anything about the lower bound on the performance of his new-found 24 | * algorithm. 25 | * 26 | *
27 | * @note Question 2 28 | * Does O^(22n) equal O^(2n) ? 29 | * 30 | *
31 | * @note Question 3 32 | * Give an example of an algorithm whose best case is equal to its worst case? 33 | * Counting Sort and Radix Sort are two algorithms which have the same best, worst and average case complexities. 34 | * 35 | *
36 | * @question Question 4 - Time complexity - Work out the time complexity for the avarager method below 37 | * @see #averager(int[]) 38 | * 39 | *
40 | * @question Question 5 - What is the complexity of the below snippet 41 | * @see #question5(int[]) 42 | * 43 | *
44 | * @question Question 6 - Consider the following snippet of code and determine its running time complexity - 45 | * @see #question6(int[]) 46 | * 47 | *
48 | * @question Question 7 - Determine the time complexity for the following snippet of code 49 | * @see #question7(int, int) 50 | * 51 | *
52 | * @question Question 8 - Determine the time complexity for the following snippet of code 53 | * @see #question8(int) 54 | * 55 | *
56 | * @question Question 9 - Determine the time complexity for the following snippet of code
57 | * @see #question9(int, int)
58 | */
59 |
60 | @SuppressWarnings({"unused", "StatementWithEmptyBody"})
61 | public class ProblemSet2 {
62 |
63 | /**
64 | * Question 4
65 | * @param A - int[]
66 | */
67 | void averager(int[] A) {
68 |
69 | float avg = 0.0f;
70 | int j, count;
71 |
72 | for (j = 0; j < A.length; j++) {
73 | avg += A[j];
74 | }
75 |
76 | avg = avg / A.length;
77 | count = j = 0;
78 |
79 | do {
80 |
81 | while (j < A.length && A[j] != avg) {
82 | j++;
83 | }
84 |
85 | if (j < A.length) {
86 | A[j++] = 0;
87 | count++;
88 | }
89 | } while (j < A.length);
90 | }
91 |
92 | /**
93 | * Question 5
94 | */
95 | public void question5(int[] array) {
96 |
97 | for( int i=0; i
5 | *
6 | * @question Problem Statement -
7 | * @example
8 | * @note Solution -
9 | * @note Time Complexity -
10 | * @note Space Complexity -
11 | * @author David Kariuki
12 | * @since /8/2022
13 | */
14 | package AceTheJavaCodingInterview.module2_data_structures;
15 |
16 | public class ClassTemplate {
17 |
18 | /**
19 | * Main method
20 | *
21 | * @param args - String[]
22 | */
23 | public static void main(String[] args) {}
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/FindMaximumInSlidingWindow.java:
--------------------------------------------------------------------------------
1 | /**
2 | * FindMaximumInSlidingWindow Class
3 | *
4 | *
5 | *
6 | * @question Given an array of integers, find the maximum value in a window. Given an integer array
7 | * and a window of size w, find the current maximum value in the window as it slides through the
8 | * entire array.
9 | * @note If the window size is greater than the array size, we will consider the entire array as a
10 | * single window.
11 | * @author David Kariuki
12 | * @since 17/8/2022
13 | */
14 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
15 |
16 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
17 |
18 | import java.util.ArrayDeque;
19 | import java.util.Deque;
20 |
21 | public class FindMaximumInSlidingWindow {
22 |
23 | /**
24 | * Main method
25 | *
26 | * @param args - String[]
27 | */
28 | public static void main(String[] args) {
29 |
30 | int[] targetList = {3, 2, 1, 2};
31 | int[][] numsList = {
32 | {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
33 | {10, 6, 9, -3, 23, -1, 34, 56, 67, -1, -4, -8, -2, 9, 10, 34, 67},
34 | {4, 5, 6, 1, 2, 3},
35 | {9, 5, 3, 1, 6, 3}
36 | };
37 |
38 | for (int i = 0; i < targetList.length; i++) {
39 |
40 | System.out.println(
41 | (i + 1) + ". Original list:\t" + DataStructuresUtils.arrayToString(numsList[i]));
42 | System.out.println(" Window size:\t\t" + targetList[i]);
43 |
44 | ArrayDeque
55 | *
56 | * @note Time complexity - The time complexity of this solution is O(n) O(n).
57 | * @note Every element is pushed and popped from the deque only once in a single traversal.
58 | * @note Space complexity - The space complexity of this solution is O(w), where w is the window
59 | * size in this case.
60 | * @param arr - int[]
61 | * @return ArrayDeque
5 | *
6 | * @question Given three integer arrays sorted in ascending order, return the smallest number found
7 | * in all three arrays.
8 | * @author David Kariuki
9 | * @since 18/8/2022
10 | */
11 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
12 |
13 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
14 |
15 | public class FindTheSmallestCommonNumber {
16 |
17 | /**
18 | * Main method
19 | *
20 | * @param args - String[]
21 | */
22 | public static void main(String[] args) {
23 |
24 | int[] v1 = new int[] {6, 7, 10, 25, 30, 63, 64};
25 | int[] v2 = new int[] {0, 4, 5, 6, 7, 8, 50};
26 | int[] v3 = new int[] {1, 6, 10, 14};
27 | System.out.println("Array 1: " + DataStructuresUtils.arrayToString(v1));
28 | System.out.println("Array 2: " + DataStructuresUtils.arrayToString(v2));
29 | System.out.println("Array 3: " + DataStructuresUtils.arrayToString(v3));
30 |
31 | Integer result = findLeastCommonNumber(v1, v2, v3);
32 | System.out.println("Least Common Number: " + result);
33 | }
34 |
35 | /**
36 | * Method to find the least common number
37 | *
38 | *
39 | *
40 | * @note Time complexity - The time complexity of the solution is linear, O (n).
41 | * @note Space complexity - The space complexity of the solution is constant, O(1) .
42 | * @param arr1 - int[]
43 | * @param arr2 - int[]
44 | * @param arr3 - int[]
45 | * @return Integer
46 | */
47 | static Integer findLeastCommonNumber(int[] arr1, int[] arr2, int[] arr3) {
48 |
49 | // Initialize starting indexes for arr1, arr2 and arr3
50 | int i = 0, j = 0, k = 0;
51 |
52 | while (i < arr1.length && j < arr2.length && k < arr3.length) {
53 |
54 | // Finding the smallest common number
55 | if (arr1[i] == arr2[j] && arr2[j] == arr3[k]) {
56 | return arr1[i];
57 | }
58 |
59 | // Increment iterator for the smallest value
60 | if (arr1[i] <= arr2[j] && arr1[i] <= arr3[k]) {
61 | i++;
62 | } else if (arr2[j] <= arr1[i] && arr2[j] <= arr3[k]) {
63 | j++;
64 | } else if (arr3[k] <= arr1[i] && arr3[k] <= arr2[j]) {
65 | k++;
66 | }
67 | }
68 |
69 | return -1;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/MaximumSumSubarrayOfSizeK.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MaximumSumSubarrayOfSizeK Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given an array of positive numbers and a positive number ‘k,’ find
7 | * the maximum sum of any contiguous subarray of size ‘k’.
8 | *
9 | * @note Solution - If you observe closely, you will realize that to calculate the sum of a
10 | * contiguous subarray, we can utilize the sum of the previous subarray. For this, consider each
11 | * subarray as a Sliding Window of size ‘k.’ To calculate the sum of the next subarray, we need
12 | * to slide the window ahead by one element. So to slide the window forward and calculate the
13 | * sum of the new position of the sliding window, we need to do two things:
14 | * Subtract the element going out of the sliding window, i.e., subtract the first element of
15 | * the window.
16 | * Add the new element getting included in the sliding window, i.e ., the element coming
17 | * right after the end of the window. This approach will save us from re-calculating the sum of
18 | * the overlapping part of the sliding window.
19 | *
20 | * @note Time Complexity - The time complexity of the above algorithm will be O(N) .
21 | * @note Space Complexity - The algorithm runs in constant space O(1).
22 | * @author David Kariuki
23 | * @since 23/8/2022
24 | */
25 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
26 |
27 | public class MaximumSumSubarrayOfSizeK {
28 |
29 | /**
30 | * Main method
31 | *
32 | * @param args - String[]
33 | */
34 | public static void main(String[] args) {
35 |
36 | System.out.println(
37 | "Maximum sum of a subarray of size K: "
38 | + findMaxSumSubArray(3, new int[] {2, 1, 5, 1, 3, 2}));
39 | System.out.println(
40 | "Maximum sum of a subarray of size K: " + findMaxSumSubArray(2, new int[] {2, 3, 4, 1, 5}));
41 | }
42 |
43 | /** Method to find max sum sub array */
44 | public static int findMaxSumSubArray(int k, int[] arr) {
45 |
46 | int windowSum = 0;
47 | int maxSum = 0;
48 | int windowStart = 0;
49 |
50 | for (int windowEnd = 0; windowEnd < arr.length; windowEnd++) {
51 |
52 | windowSum += arr[windowEnd]; // Add the next element
53 |
54 | // Slide the window, we don't need to slide if we've no hit the
55 | // required window size of k
56 | if (windowEnd >= k - 1) {
57 | maxSum = Math.max(maxSum, windowSum);
58 | windowSum -= arr[windowStart]; // subtract the element going out
59 | windowStart++; // slide the window ahead
60 | }
61 | }
62 |
63 | return maxSum;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/MergeAnArrayWithOverlappingIntervals.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MergeAnArrayWithOverlappingIntervals Class
3 | *
4 | *
5 | *
6 | * @question We’re given an array of interval pairs as input where each interval has a start and end
7 | * timestamp. The input array is sorted by starting timestamps. Merge the overlapping intervals
8 | * and return a new output array.
9 | *
10 | * @note Solution - This problem can be solved in a simple linear scan algorithm. We know that the
11 | * input is sorted by starting timestamps. Here is the approach we are following:
12 | * Using the given list of input intervals, we keep merged intervals in the output list.
13 | * For each interval in the input list: If the input interval is overlapping with the last
14 | * interval in the output list, then we merge these two intervals and update the last interval
15 | * of the output list with the merged interval.
16 | * Otherwise, we add an input interval to the output list.
17 | * @author David Kariuki
18 | * @since 22/8/2022
19 | */
20 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
21 |
22 | import AceTheJavaCodingInterview.module2_data_structures.tuples.Interval;
23 |
24 | import java.util.ArrayList;
25 | import java.util.Arrays;
26 |
27 | @SuppressWarnings("StringConcatenationInLoop")
28 | public class MergeAnArrayWithOverlappingIntervals {
29 |
30 | /**
31 | * Main method
32 | *
33 | * @param args - String[]
34 | */
35 | public static void main(String[] args) {
36 |
37 | Interval[] v1 = {new Interval(1, 5), new Interval(3, 7), new Interval(4, 6)};
38 |
39 | Interval[] v2 = {
40 | new Interval(1, 5), new Interval(4, 6), new Interval(6, 8), new Interval(11, 15)
41 | };
42 |
43 | Interval[] v3 = {
44 | new Interval(3, 7), new Interval(6, 8), new Interval(10, 12), new Interval(11, 15)
45 | };
46 |
47 | Interval[] v4 = {new Interval(1, 5)};
48 |
49 | Interval[][] vList = {v1, v2, v3, v4};
50 |
51 | for (int i = 0; i < vList.length; i++) {
52 |
53 | ArrayList
5 | *
6 | * @note
7 | * @author David Kariuki
8 | * @since 14/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
11 |
12 | @SuppressWarnings({"ForLoopReplaceableByForEach", "SameParameterValue"})
13 | public class OneDimensionalArrays {
14 |
15 | public static final int[] myArray = new int[4]; // Array declaration
16 |
17 | public static void main(String[] args) {
18 |
19 | initArray(); // Array initialization
20 | showArrayElements();
21 | updateArrayElement(2, 50);
22 | showArrayElements();
23 | }
24 |
25 | /**
26 | * Method to initialize array
27 | */
28 | public static void initArray() {
29 |
30 | // Adding elements in an array
31 | myArray[0] = 10;
32 | myArray[1] = 20;
33 | myArray[2] = 30;
34 | myArray[3] = 40;
35 | }
36 |
37 | /**
38 | * Method to update array element
39 | *
40 | */
41 | public static void updateArrayElement(final int index, final int value) {
42 | myArray[index] = value;
43 | }
44 |
45 | /** Method to show array elements */
46 | public static void showArrayElements() {
47 |
48 | System.out.println("\nPrinting array elements\n");
49 |
50 | // Accessing elements in an array
51 | for (int i = 0; i < myArray.length; i++) {
52 | System.out.println(myArray[i]);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/PairWithTargetSum.java:
--------------------------------------------------------------------------------
1 | /**
2 | * PairWithTargetSum Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given an array of sorted numbers and a target sum, find a pair in
7 | * the array whose sum is equal to the given target.
8 | * Write a function to return the indices of the two numbers (i.e. the pair) such that they
9 | * add up to the given target.
10 | * @note Example 1:
11 | * Input: [1, 2, 3, 4, 6], target=6 Output: [1, 3] Explanation: The numbers at index 1 and 3
12 | * add up to 6: 2 + 4 = 6
13 | * @note Example 2:
14 | * Input: [2, 5, 9, 11], target=11 Output: [0, 2] Explanation: The numbers at index 0 and 2
15 | * add up to 11: 2 + 9 = 11
16 | * @note Solution - Since the given array is sorted, a brute-force solution could be to iterate
17 | * through the array, taking one number at a time and searching for the second number through
18 | * Binary Search. The time complexity of this algorithm will be O(N*logN). Can we do better than
19 | * this?
20 | *
21 | * We can follow the Two Pointers approach. We will start with one pointer pointing to the
22 | * beginning of the array and another pointing at the end. At every step, we will see if the
23 | * numbers pointed by the two pointers add up to the target sum. If they do, we have found our
24 | * pair; otherwise, we will do one of two things:
25 | * 1. If the sum of the two numbers pointed by the two pointers is greater than the target
26 | * sum, this means that we need a pair with a smaller sum. So, to try more pairs, we can
27 | * decrement the end-pointer.
28 | * 2. If the sum of the two numbers pointed by the two pointers is smaller than the target
29 | * sum, this means that we need a pair with a larger sum. So, to try more pairs, we can
30 | * increment the start-pointer.
31 | *
32 | * @note Time Complexity - The time complexity of the above algorithm will be O(N), where N is the
33 | * total number of elements in the given array.
34 | * @note Space Complexity - The space complexity will also be O(N), as, in the worst case, we will
35 | * be pushing N numbers in the HashTable.
36 | * @author David Kariuki
37 | * @since 24/8/2022
38 | */
39 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
40 |
41 | public class PairWithTargetSum {
42 |
43 | /**
44 | * Main method
45 | *
46 | * @param args - String[]
47 | */
48 | public static void main(String[] args) {
49 |
50 | int[] result = PairWithTargetSum.search(new int[] {1, 2, 3, 4, 6}, 6);
51 | System.out.println("Pair with target sum: [" + result[0] + ", " + result[1] + "]");
52 |
53 | result = PairWithTargetSum.search(new int[] {2, 5, 9, 11}, 11);
54 | System.out.println("Pair with target sum: [" + result[0] + ", " + result[1] + "]");
55 | }
56 |
57 | /**
58 | * Method to search array
59 | *
60 | * @param arr - int[]
61 | * @param targetSum -
62 | * @return int[]
63 | */
64 | public static int[] search(int[] arr, int targetSum) {
65 |
66 | int left = 0;
67 | int right = arr.length - 1;
68 |
69 | while (left < right) {
70 |
71 | int currentSum = arr[left] + arr[right];
72 |
73 | // Check if current sum equals target sum
74 | if (currentSum == targetSum) {
75 | return new int[] {left, right};
76 | }
77 |
78 | // Compare current and target sum
79 | if (currentSum > targetSum) {
80 | right--; // We need a pair with a smaller sum
81 | } else {
82 | left++; // We need a pair with a bigger sum
83 | }
84 | }
85 |
86 | return new int[] {-1, -1}; // Return int pair with -1
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/Permutations.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Permutations Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement# Given a set of distinct numbers, find all of its permutations.
7 | * Permutation is defined as the re-arranging of the elements of the set.
8 | * @note Example, {1, 2, 3} has the following six permutations:
9 | * {1, 2, 3} {1, 3, 2} {2, 1, 3} {2, 3, 1} {3, 1, 2} {3, 2, 1}
10 | * If a set has n distinct elements it will have n! n! permutations.
11 | * @note Solution This problem follows the Subsets pattern ({@link
12 | * AceTheJavaCodingInterview.module2_data_structures.arrays.Subset}) and, we can follow a
13 | * similar Breadth First Search (BFS) approach. However, unlike Subsets, every permutation must
14 | * contain all the numbers.
15 | * Let’s take the example-1 mentioned above to generate all the permutations. Following a BFS
16 | * approach, we will consider one number at a time:
17 | * 1. If the given set is empty then we have only an empty permutation set: []
18 | * 2. Let’s add the first element (1), the permutations will be: [1]
19 | * 3. Let’s add the second element (3), the permutations will be: [3,1], [1,3]
20 | * 4. Let’s add the third element (5), the permutations will be: [5,3, 1], [3,5,1], [3,1,5],
21 | * [5,1,3], [1,5,3], [1,3,5]
22 | *
23 | * Let’s analyze the permutations in the 3rd and 4th steps. How can we generate permutations
24 | * in the 4th step from the permutations of the 3rd step?
25 | * If we look closely, we will realize that when we add a new number (5), we take each
26 | * permutation of the previous step and insert the new number in every position to generate the
27 | * new permutations. For example, inserting 5 in different positions of [3,1] will give us the
28 | * following permutations:
29 | * Inserting 5 before 3: [5,3,1]
30 | * Inserting 5 between 3 and 1: [3,5,1]
31 | * Inserting 5 after 1: [3,1,5]
32 | *
33 | * @note Time complexity - We know that there are a total of N! permutations of a set with N
34 | * numbers. In the algorithm above, we are iterating through all of these permutations with the
35 | * help of the two for loops. In each iteration, we go through all the current permutations to
36 | * insert a new number in them. To insert a number into a permutation of size N will take O(N),
37 | * which makes the overall time complexity of our algorithm O(N*N!).
38 | * @note Space complexity - All the additional space used by our algorithm is for the result list
39 | * and the queue to store the intermediate permutations. If you see closely, at any time, we
40 | * don’t have more than N! permutations between the result list and the queue. Therefore, the
41 | * overall space complexity to store N! permutations each containing N elements will be O(N*N!).
42 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.Subset
43 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.SubsetsWithDuplicates
44 | * @author David Kariuki
45 | * @since 24/8/2022
46 | */
47 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
48 |
49 | import java.util.ArrayList;
50 | import java.util.LinkedList;
51 | import java.util.List;
52 | import java.util.Queue;
53 |
54 | public class Permutations {
55 |
56 | /**
57 | * Main method
58 | *
59 | * @param args - String[]
60 | */
61 | public static void main(String[] args) {
62 |
63 | List
5 | *
6 | * @question Problem Statement Given an array of positive numbers and a positive number ‘S,’ find
7 | * the length of the smallest contiguous subarray whose sum is greater than or equal to ‘S’.
8 | * Return 0 if no such subarray exists.
9 | *
10 | * @note Solution - This problem follows the Sliding Window pattern. In this problem, the sliding
11 | * window size is not fixed. Here is how we will solve this problem:
12 | * First, we will add-up elements from the beginning of the array until their sum becomes
13 | * greater than or equal to ‘S.’
14 | * These elements will constitute our sliding window. We are asked to find the smallest such
15 | * window having a sum greater than or equal to ‘S.’ We will remember the length of this window
16 | * as the smallest window so far.
17 | * After this, we will keep adding one element in the sliding window (i.e., slide the window
18 | * ahead) in a stepwise fashion.
19 | * In each step, we will also try to shrink the window from the beginning. We will shrink the
20 | * window until the window’s sum is smaller than ‘S’ again. This is needed as we intend to find
21 | * the smallest window. This shrinking will also happen in multiple steps; in each step, we will
22 | * do two things: - Check if the current window length is the smallest so far, and if so,
23 | * remember its length. -Subtract the first element of the window from the running sum to shrink
24 | * the sliding window.
25 | *
26 | * @note Time Complexity - The time complexity of the above algorithm will be O(N) . The outer for
27 | * loop runs for all elements, and the inner while loop processes each element only once;
28 | * therefore, the time complexity of the algorithm will be O(N+N), which is asymptotically
29 | * equivalent to O(N) .
30 | * @note Space Complexity - The algorithm runs in constant space O(1) .
31 | * @author David Kariuki
32 | * @since 23/8/2022
33 | */
34 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
35 |
36 | public class SmallestSubarrayWithAGreaterSum {
37 |
38 | /**
39 | * Main method
40 | *
41 | * @param args - String[]
42 | */
43 | public static void main(String[] args) {
44 |
45 | int result = findMinSubArray(7, new int[] {2, 1, 5, 2, 3, 2});
46 | System.out.println("Smallest subarray length: " + result);
47 | result = findMinSubArray(7, new int[] {2, 1, 5, 2, 8});
48 | System.out.println("Smallest subarray length: " + result);
49 | result = findMinSubArray(8, new int[] {3, 4, 1, 1, 6});
50 | System.out.println("Smallest subarray length: " + result);
51 | }
52 |
53 | /** Method to find min sub array */
54 | public static int findMinSubArray(int S, int[] arr) {
55 |
56 | int windowSum = 0, minLength = Integer.MAX_VALUE;
57 | int windowStart = 0;
58 | for (int windowEnd = 0; windowEnd < arr.length; windowEnd++) {
59 | windowSum += arr[windowEnd]; // add the next element
60 | // shrink the window as small as possible until the 'windowSum' is smaller than 'S'
61 | while (windowSum >= S) {
62 | minLength = Math.min(minLength, windowEnd - windowStart + 1);
63 | windowSum -= arr[windowStart]; // subtract the element going out
64 | windowStart++; // slide the window ahead
65 | }
66 | }
67 |
68 | return minLength == Integer.MAX_VALUE ? 0 : minLength;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/SquaringASortedArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * SquaringASortedArray Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given a sorted array, create a new array containing squares of all
7 | * the numbers of the input array in the sorted order.
8 | *
9 | * @note Solution - use two-pointers starting at both ends of the input array. At any step,
10 | * whichever pointer gives us the bigger square, we add it to the result array and move to the
11 | * next/previous number according to the pointer.
12 | *
13 | * @note Time complexity - The above algorithm’s time complexity will be O(N) O(N) as we are
14 | * iterating the input array only once.
15 | *
16 | * @note Space complexity - The above algorithm’s space complexity will also be O(N) O(N) ; this
17 | * space will be used for the output array.
18 | * @author David Kariuki
19 | * @since 23/8/2022
20 | */
21 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
22 |
23 | public class SquaringASortedArray {
24 |
25 | /**
26 | * Main method
27 | *
28 | * @param args - String[]
29 | */
30 | public static void main(String[] args) {
31 | int[] result = SquaringASortedArray.makeSquares(new int[] {-2, -1, 0, 2, 3});
32 | for (int num : result) System.out.print(num + " ");
33 | System.out.println();
34 |
35 | result = SquaringASortedArray.makeSquares(new int[] {-3, -1, 0, 1, 2});
36 | for (int num : result) System.out.print(num + " ");
37 | System.out.println();
38 | }
39 |
40 | /**
41 | * Method to make squares
42 | *
43 | * @param arr - int[]
44 | * @return int[]
45 | */
46 | public static int[] makeSquares(int[] arr) {
47 |
48 | int n = arr.length;
49 | int[] squares = new int[n];
50 |
51 | int highestSquareIdx = n - 1;
52 |
53 | int left = 0;
54 | int right = arr.length - 1;
55 |
56 | while (left <= right) {
57 |
58 | int leftSquare = arr[left] * arr[left];
59 | int rightSquare = arr[right] * arr[right];
60 |
61 | if (leftSquare > rightSquare) {
62 | squares[highestSquareIdx--] = leftSquare;
63 | left++;
64 | } else {
65 | squares[highestSquareIdx--] = rightSquare;
66 | right--;
67 | }
68 | }
69 |
70 | return squares;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/SubArraysWithProductLessThanTarget.java:
--------------------------------------------------------------------------------
1 | /**
2 | * SubArraysWithProductLessThanTarget Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given an array with positive numbers and a positive target number,
7 | * find all of its contiguous sub-arrays whose product is less than the target number.
8 | * @example Example 1:
9 | * Input: [2, 5, 3, 10], target=30 Output: [2], [5], [2, 5], [3], [5, 3], [10] Explanation:
10 | * There are six contiguous sub-arrays whose product is less than the target.
11 | * @example Example 2:
12 | * Input: [8, 2, 6, 5], target=50 Output: [8], [2], [8, 2], [6], [2, 6], [5], [6, 5]
13 | * Explanation: There are seven contiguous sub-arrays whose product is less than the target.
14 | * @note Solution - This problem follows the Sliding Window and the Two Pointers pattern and shares
15 | * similarities with Triplets with Smaller Sum
16 | * ({@link
17 | * AceTheJavaCodingInterview.module2_data_structures.arrays.TripletsWithSmallerSum_ReturnCount},
18 | * {@link
19 | * AceTheJavaCodingInterview.module2_data_structures.arrays.TripletsWithSmallerSum_ReturnList})
20 | * with two differences:
21 | * In this problem, the input array is not sorted. Instead of finding triplets with sum less
22 | * than a target, we need to find all sub-arrays having a product less than the target. The
23 | * implementation will be quite similar to Triplets with Smaller Sum.
24 | * @note Time Complexity -
25 | * @note Space Complexity -
26 | * @author David Kariuki
27 | * @since 26/8/2022
28 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.TripletsWithSmallerSum_ReturnCount
29 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.TripletsWithSmallerSum_ReturnList
30 | */
31 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
32 |
33 | import java.util.ArrayList;
34 | import java.util.LinkedList;
35 | import java.util.List;
36 |
37 | public class SubArraysWithProductLessThanTarget {
38 |
39 | /**
40 | * Main method
41 | *
42 | * @param args - String[]
43 | */
44 | public static void main(String[] args) {
45 | System.out.println(
46 | SubArraysWithProductLessThanTarget.findSubArrays(new int[] {2, 5, 3, 10}, 30));
47 | System.out.println(
48 | SubArraysWithProductLessThanTarget.findSubArrays(new int[] {8, 2, 6, 5}, 50));
49 | }
50 |
51 | /**
52 | * Method to find sub arrays
53 | *
54 | * @param arr - int[]
55 | * @param target - int
56 | * @return List
5 | *
6 | * @question Problem Statement - Given a set with distinct elements, find all of its distinct
7 | * subsets.
8 | *
9 | * @note Solution - To generate all subsets of the given set, we can use the Breadth First Search
10 | * (BFS) approach. We can start with an empty set, iterate through all numbers one-by-one, and
11 | * add them to existing sets to create new subsets.
12 | * Let’s take the example-2 mentioned above to go through each step of our algorithm:
13 | * Given set: [1, 5, 3]
14 | * Start with an empty set: [[]] Add the first number (1) to all the existing subsets to
15 | * create new subsets: [[], [1]]; Add the second number (5) to all the existing subsets: [[],
16 | * [1], [5], [1,5]]; Add the third number (3) to all the existing subsets: [[], [1], [5], [1,5],
17 | * [3], [1,3], [5,3], [1,5,3]].
18 | *
19 | * @note Time complexity - Since, in each step, the number of subsets doubles as we add each element
20 | * to all the existing subsets, therefore, we will have a total of O(2^N) subsets, where ‘N’ is
21 | * the total number of elements in the input set. And since we construct a new subset from an
22 | * existing set, therefore, the time complexity of the above algorithm will be O(N*2^N).
23 | *
24 | * @note Space complexity - All the additional space used by our algorithm is for the output list.
25 | * Since we will have a total of O(2^N) O(2 N ) subsets, and each subset can take up to O(N)
26 | * space, therefore, the space complexity of our algorithm will be O(N*2^N).
27 | *
28 | * @author David Kariuki
29 | * @since 23/8/2022
30 | */
31 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
32 |
33 | import java.util.ArrayList;
34 | import java.util.List;
35 |
36 | public class Subset {
37 |
38 | /**
39 | * Main method
40 | *
41 | * @param args - String[]
42 | */
43 | public static void main(String[] args) {
44 |
45 | List
5 | *
6 | * @question Problem Statement - Given a set of numbers that might contain duplicates, find all of
7 | * its distinct subsets.
8 | * @note Solution - This problem follows the Subsets pattern and we can follow a similar Breadth
9 | * First Search (BFS) approach. The only additional thing we need to do is handle duplicates.
10 | * Since the given set can have duplicate numbers, if we follow the same approach discussed in
11 | * Subsets, we will end up with duplicate subsets, which is not acceptable. To handle this, we
12 | * will do two extra things:
13 | * Sort all numbers of the given set. This will ensure that all duplicate numbers are next to
14 | * each other. Follow the same BFS approach but whenever we are about to process a duplicate
15 | * (i.e., when the current and the previous numbers are same), instead of adding the current
16 | * number (which is a duplicate) to all the existing subsets, only add it to the subsets which
17 | * were created in the previous step.
18 | *
19 | * @note Example
20 | * Given set: [1, 5, 3, 3] Sorted set: [1, 3, 3, 5]
21 | * Start with an empty set: [[]]
22 | * Add the first number (1) to all the existing subsets to create new subsets: [[], [1]];
23 | * Add the second number (3) to all the existing subsets: [[], [1], [3], [1,3]].
24 | * The next number (3) is a duplicate. If we add it to all existing subsets we will get:
25 | * [[], [1], [3], [1,3], [3], [1,3], [3,3], [1,3,3]]
26 | * We got two duplicate subsets: [3], [1,3] Whereas we only needed the new subsets: [3,3],
27 | * [1,3,3]
28 | * To handle this instead of adding (3) to all the existing subsets, we only add it to the
29 | * new subsets which were created in the previous (3rd) step:
30 | * [[], [1], [3], [1,3], [3,3], [1,3,3]]
31 | * Finally, add the forth number (5) to all the existing subsets:
32 | * [[], [1], [3], [1,3], [3,3], [1,3,3], [5], [1,5], [3,5], [1,3, 5], [3, 3,5], [1,3,3,5]]
33 | *
34 | * @note Time complexity - Since, in each step, the number of subsets doubles (if not duplicate) as
35 | * we add each element to all the existing subsets, therefore, we will have a total of O(2^N)
36 | * subsets, where ‘N’ is the total number of elements in the input set. And since we construct a
37 | * new subset from an existing set, therefore, the time complexity of the above algorithm will
38 | * be O(N*2^N) O(N∗2 N ) .
39 | * Space complexity# All the additional space used by our algorithm is for the output list.
40 | * Since, at most, we will have a total of O(2^N) subsets, and each subset can take up to O(N)
41 | * space, therefore, the space complexity of our algorithm will be O(N*2^N).
42 | * @author David Kariuki
43 | * @since 24/8/2022
44 | */
45 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
46 |
47 | import java.util.ArrayList;
48 | import java.util.Arrays;
49 | import java.util.List;
50 |
51 | @SuppressWarnings("SameParameterValue")
52 | public class SubsetsWithDuplicates {
53 |
54 | /**
55 | * Main method
56 | *
57 | * @param args - String[]
58 | */
59 | public static void main(String[] args) {
60 |
61 | List
5 | *
6 | * @question Problem Statement# Given an array of unsorted numbers and a target number, find a
7 | * triplet in the array whose sum is as close to the target number as possible, return the sum
8 | * of the triplet. If there are more than one such triplet, return the sum of the triplet with
9 | * the smallest sum.
10 | * @note Solution - This problem follows the Two Pointers pattern and is quite similar to Triplet
11 | * Sum to Zero({@link
12 | * AceTheJavaCodingInterview.module2_data_structures.arrays.TripletSumToZero}).
13 | * We can follow a similar approach to iterate through the array, taking one number at a
14 | * time. At every step, we will save the difference between the triplet and the target number,
15 | * so that in the end, we can return the triplet with the closest sum.
16 | * @note Time Complexity - Sorting the array will take O(N * logN). Overall, the function will take
17 | * O(N * logN + N^2), which is asymptotically equivalent to O(N^2).
18 | * @note Space Complexity - The above algorithm’s space complexity will be O(N), which is required
19 | * for sorting.
20 | * @author David Kariuki
21 | * @since 25/8/2022
22 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.TripletSumToZero
23 | */
24 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
25 |
26 | import java.util.Arrays;
27 |
28 | public class TripletSumCloseToTarget {
29 |
30 | /**
31 | * Main method
32 | *
33 | * @param args - String[]
34 | */
35 | public static void main(String[] args) {
36 |
37 | System.out.println(TripletSumCloseToTarget.searchTriplet(new int[] {-2, 0, 1, 2}, 2));
38 | System.out.println(TripletSumCloseToTarget.searchTriplet(new int[] {-3, -1, 1, 2}, 1));
39 | System.out.println(TripletSumCloseToTarget.searchTriplet(new int[] {1, 0, 1, 1}, 100));
40 | }
41 |
42 | /**
43 | * Method to search for triplet
44 | *
45 | * @param arr - int[]
46 | * @param targetSum - int
47 | */
48 | public static int searchTriplet(int[] arr, int targetSum) {
49 |
50 | if (arr == null || arr.length < 3) {
51 | throw new IllegalArgumentException();
52 | }
53 |
54 | Arrays.sort(arr);
55 |
56 | int smallestDifference = Integer.MAX_VALUE;
57 |
58 | for (int i = 0; i < arr.length - 2; i++) {
59 |
60 | int left = i + 1;
61 | int right = arr.length - 1;
62 |
63 | while (left < right) {
64 |
65 | // Comparing sum of 3 numbers to the targetSum can cause overflow so,
66 | // try to find a target difference
67 | int targetDiff = targetSum - arr[i] - arr[left] - arr[right];
68 |
69 | if (targetDiff == 0) {
70 | // Found triplet with exact sum thus return sum of all the numbers
71 | return targetSum;
72 | }
73 |
74 | // the second part of the above 'if' is to handle the smallest sum when we have more than
75 | // one solution
76 | if (Math.abs(targetDiff) < Math.abs(smallestDifference)
77 | || (Math.abs(targetDiff) == Math.abs(smallestDifference)
78 | && targetDiff > smallestDifference))
79 | smallestDifference = targetDiff; // save the closest and the biggest difference
80 |
81 | if (targetDiff > 0) {
82 | left++; // we need a triplet with a bigger sum
83 | } else {
84 | right--; // we need a triplet with a smaller sum
85 | }
86 | }
87 | }
88 |
89 | return targetSum - smallestDifference;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/TripletSumToZero.java:
--------------------------------------------------------------------------------
1 | /**
2 | * TripletSumToZero Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given an array of unsorted numbers, find all unique triplets in it
7 | * that add up to zero.
8 | *
9 | * @example Example 1:
10 | * Input: [-3, 0, 1, 2, -1, 1, -2] Output: [-3, 1, 2], [-2, 0, 2], [-2, 1, 1], [-1, 0, 1]
11 | * Explanation: There are four unique triplets whose sum is equal to zero. >
12 | * @example Example 2:
13 | * Input: [-5, 2, -1, -2, 3] Output: [[-5, 2, 3], [-2, -1, 3]] Explanation: There are two
14 | * unique triplets whose sum is equal to zero.
15 | * @solution Solution - This problem follows the Two Pointers pattern and shares similarities with
16 | * Pair with Target Sum ({@link
17 | * AceTheJavaCodingInterview.module2_data_structures.arrays.PairWithTargetSum}). A couple of
18 | * differences are that the input array is not sorted and instead of a pair we need to find
19 | * triplets with a target sum of zero.
20 | * To follow a similar approach, first, we will sort the array and then iterate through it
21 | * taking one number at a time. Let’s say during our iteration we are at number ‘X’, so we need
22 | * to find ‘Y’ and ‘Z’ such that X + Y + Z == 0. At this stage, our problem translates into
23 | * finding a pair whose sum is equal to -X (as from the above equation Y + Z == -X).
24 | *
25 | * Another difference from Pair with Target Sum({@link
26 | * AceTheJavaCodingInterview.module2_data_structures.arrays.PairWithTargetSum}) is that we need
27 | * to find all the unique triplets. To handle this, we have to skip any duplicate number. Since
28 | * we will be sorting the array, so all the duplicate numbers will be next to each other and are
29 | * easier to skip.
30 | * @note Time complexity - Sorting the array will take O(N * logN). The searchPair() function will
31 | * take O(N). As we are calling searchPair() for every number in the input array, this means
32 | * that overall searchTriplets() will take O(N * logN + N^2), which is asymptotically equivalent
33 | * to O(N^2).
34 | * @note Space complexity - Ignoring the space required for the output array, the space complexity
35 | * of the above algorithm will be O(N) which is required for sorting.
36 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.PairWithTargetSum
37 | * @see AceTheJavaCodingInterview.module2_data_structures.hash_tables.PairWithTargetSum
38 | * @author David Kariuki
39 | * @since 25/8/2022
40 | */
41 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
42 |
43 | import java.util.ArrayList;
44 | import java.util.Arrays;
45 | import java.util.List;
46 |
47 | public class TripletSumToZero {
48 |
49 | /**
50 | * Main method
51 | *
52 | * @param args - String[]
53 | */
54 | public static void main(String[] args) {
55 |
56 | System.out.println(TripletSumToZero.searchTriplets(new int[] {-3, 0, 1, 2, -1, 1, -2}));
57 | System.out.println(TripletSumToZero.searchTriplets(new int[] {-5, 2, -1, -2, 3}));
58 | }
59 |
60 | /**
61 | * Method to search for triplets
62 | *
63 | * @param arr - int[]
64 | * @return List
5 | *
6 | * @question Problem Statement - Write a function to return the list of all such triplets instead of
7 | * the count. How will the time complexity change in this case?
8 | * @note Solution - Following a similar approach we can create a list containing all the triplets.
9 | * Another simpler approach could be to check every triplet of the array with three nested loops
10 | * and create a list of triplets that meet the required condition.
11 | * @note Time Complexity - Sorting the array will take O(N * logN). The searchPair(), in this case,
12 | * will take O(N^2). The main while loop will run in O(N)but the nested for loop can also take
13 | * O(N) - this will happen when the target sum is bigger than every triplet in the array.
14 | * So, overall searchTriplets() will take O(N * logN + N^3), which is asymptotically
15 | * equivalent to O(N^3).
16 | * @note Space Complexity - Ignoring the space required for the output array, the space complexity
17 | * of the above algorithm will be O(N) which is required for sorting.
18 | * @author David Kariuki
19 | * @since 26/8/2022
20 | * @see AceTheJavaCodingInterview.module2_data_structures.arrays.TripletSumToZero
21 | */
22 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
23 |
24 | import java.util.ArrayList;
25 | import java.util.Arrays;
26 | import java.util.List;
27 |
28 | public class TripletsWithSmallerSum_ReturnCount {
29 |
30 | /**
31 | * Main method
32 | *
33 | * @param args - String[]
34 | */
35 | public static void main(String[] args) {
36 | System.out.println(
37 | TripletsWithSmallerSum_ReturnCount.searchTriplets(new int[] {-1, 0, 2, 3}, 3));
38 | System.out.println(
39 | TripletsWithSmallerSum_ReturnCount.searchTriplets(new int[] {-1, 4, 2, 1, 3}, 5));
40 | }
41 |
42 | /**
43 | * Method to search for triplets
44 | *
45 | * @param arr - int[]
46 | * @param target - int
47 | * @return List
5 | *
6 | * @question Problem Statement - Given an array arr of unsorted numbers and a target sum, count all
7 | * triplets in it such that arr[i] + arr[j] + arr[k] < target where i, j, and k are three
8 | * different indices. Write a function to return the count of such triplets.
9 | * @example Example 1:
10 | * Input: [-1, 0, 2, 3], target=3 Output: 2 Explanation: There are two triplets whose sum is
11 | * less than the target: [-1, 0, 3], [-1, 0, 2]
12 | * @example Example 2:
13 | * Input: [-1, 4, 2, 1, 3], target=5 Output: 4 Explanation: There are four triplets whose sum
14 | * is less than the target: [-1, 1, 4], [-1, 1, 3], [-1, 1, 2], [-1, 2, 3]
15 | * @note Solution - This problem follows the Two Pointers pattern and shares similarities with
16 | * Triplet Sum to Zero ({@link
17 | * AceTheJavaCodingInterview.module2_data_structures.arrays.TripletSumToZero}). The only
18 | * difference is that, in this problem, we need to find the triplets whose sum is less than the
19 | * given target. To meet the condition i != j != k we need to make sure that each number is not
20 | * used more than once.
21 | * Following a similar approach, first, we can sort the array and then iterate through it,
22 | * taking one number at a time. Let’s say during our iteration we are at number ‘X’, so we need
23 | * to find ‘Y’ and ‘Z’ such that X + Y + Z < target X+Y+Z
5 | *
6 | * @note 2D Arrays
7 | * @author David Kariuki
8 | * @since 14/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays;
11 |
12 | @SuppressWarnings("SameParameterValue")
13 | public class TwoDimensionalArrays {
14 |
15 | static int[][] twoDArray;
16 |
17 | public static void main(String[] args) {
18 |
19 | twoDArray = create2DArray(3, 4); // Create 2D array
20 |
21 | init2DArray(0, 1, 10); // Adding 10 at Row 0 Column 1
22 | }
23 |
24 | /**
25 | * Method to create 2D array
26 | *
27 | * @param rows - int
28 | * @param columns - int
29 | */
30 | public static int[][] create2DArray(int rows, int columns) {
31 |
32 | return new int[rows][columns]; // Create array
33 | }
34 |
35 | public static void init2DArray(int row, int column, int value) {
36 | twoDArray[row][column] = value;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/_arrays.md:
--------------------------------------------------------------------------------
1 | # Arrays
2 |
3 | ### Array Indexing
4 |
5 | Each data element is assigned a numerical value called the index, which corresponds to the position of that item in the array. It is important to note that the value of the index is non-negative and always starts from zero. So the first
6 | element of an array will be stored at index 0 and the last one at index size-1.
7 |
8 | An index makes it possible to access the contents of the array directly. Otherwise, we would have to traverse through the whole array to access a single element.
9 |
10 | ### Types of Arrays#
11 |
12 | Arrays can store **primitive** data-type values (e.g., `int`, `char`, `floats`, `boolean`, `byte`, `short`, `long`, etc.), **non-primitive** data-type values (e.g., Java Objects, etc.) or it can even hold references of other arrays. That
13 | divides the arrays into two categories:
14 |
15 | - One Dimensional Array.
16 | - Multi-Dimensional Array.
17 |
18 |
5 | *
6 | * @question We are given an array of integers, nums, sorted in ascending order, and an integer
7 | * value, target. If the target exists in the array, return its index. If the target does not
8 | * exist, then return -1. This class uses Iteration.
9 | * @author David Kariuki
10 | * @since 17/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
13 |
14 | public class BinarySearchOnSortedArray_Iterative {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] nums = new int[] {1, 3, 9, 10, 12};
24 | int target = 9;
25 | }
26 |
27 | /**
28 | * Method to perform binary search
29 | *
30 | *
31 | *
32 | * @note Time complexity - The time complexity of this solution is logarithmic, O(log n)
33 | * @note Space complexity - The space complexity of this solution is logarithmic, O(log n) because
34 | * the recursive approach consumes memory on the stack.
35 | * @param nums - int[]
36 | * @param target - int
37 | * @return int
38 | */
39 | static int binarySearch(int[] nums, int target) {
40 |
41 | // Set start
42 | int start = 0;
43 | int end = nums.length - 1;
44 |
45 | for (int i = 0; i < nums.length; i++) {
46 |
47 | // Finding the mid using floor division
48 | // Using this method to prevent an overflow
49 | int mid = start + ((end - start) / 2);
50 |
51 | // Target value is present at the middle of the array
52 | if (nums[mid] == target) {
53 | return nums[mid];
54 |
55 | // Target value is present in the low subarray
56 | } else if (nums[mid] > target) {
57 | end = mid - 1;
58 |
59 | // Target value is present in the high subarray
60 | } else if (target > nums[mid]) {
61 | start = mid + 1;
62 | }
63 | }
64 |
65 | return -1;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/BinarySearchOnSortedArray_Recursive.java:
--------------------------------------------------------------------------------
1 | /**
2 | * BinarySearchOnSortedArray_Recursive Class
3 | *
4 | *
5 | *
6 | * @question We are given an array of integers, nums, sorted in ascending order, and an integer *
7 | * value, target. If the target exists in the array, return its index. If the target does not *
8 | * exist, then return -1.
9 | * This class uses Recursion.
10 | * @author David Kariuki
11 | * @since 17/8/2022
12 | */
13 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
14 |
15 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
16 |
17 | public class BinarySearchOnSortedArray_Recursive {
18 |
19 | /**
20 | * Main method
21 | *
22 | * @param args - String[]
23 | */
24 | public static void main(String[] args) {
25 |
26 | int[][] numsLists = {{}, {0, 1}, {1, 2, 3}, {-1, 0, 3, 5, 9, 12}, {-1, 0, 3, 5, 9, 12}};
27 | int[] targetList = {12, 1, 3, 9, 2};
28 |
29 | for (int i = 0; i < numsLists.length; i++) {
30 |
31 | int[] nums = numsLists[i];
32 | int target = targetList[i];
33 | int index = binarySearch(nums, target);
34 |
35 | System.out.println(i + 1 + ". Array to search: " + DataStructuresUtils.arrayToString(nums));
36 | System.out.println(" Target: " + targetList[i]);
37 |
38 | if (index != -1) {
39 | System.out.println(" " + target + " exists in the array and its index is " + index);
40 | } else {
41 | System.out.println(
42 | " " + target + " does not exist in the array so the return value is " + index);
43 | }
44 | }
45 | }
46 |
47 | /**
48 | * Method to perform binary search
49 | *
50 | *
51 | *
52 | * @note Time complexity - The time complexity of this solution is logarithmic, O(log n)
53 | * @note Space complexity - The space complexity of this solution is constant, O(1).
54 | * @param nums - int[]
55 | * @param target - int
56 | * @return int
57 | */
58 | public static int binarySearch(int[] nums, int target) {
59 | return binarySearchRecursive(nums, target, 0, nums.length - 1);
60 | }
61 |
62 | /**
63 | * Method to perform binary search
64 | *
65 | *
66 | *
67 | * @note Time complexity - The time complexity of this solution is logarithmic, O(log n)
68 | * @note Space complexity - The space complexity of this solution is constant, O(1).
69 | * @param nums - int[]
70 | * @param target - int
71 | * @param low - int
72 | * @param high - int
73 | * @return int
74 | */
75 | public static int binarySearchRecursive(int[] nums, int target, int low, int high) {
76 |
77 | if (low > high) {
78 | return -1;
79 | }
80 |
81 | // Finding the mid using floor division
82 | int mid = low + ((high - low) / 2);
83 |
84 | // Target value is present at the middle of the array
85 | if (nums[mid] == target) {
86 | return mid;
87 | }
88 |
89 | // Target value is present in the low subarray
90 | else if (target < nums[mid]) {
91 | binarySearchRecursive(nums, target, low, mid - 1);
92 |
93 | // Target value is present in the high subarray
94 | } else if (target > nums[mid]) {
95 | binarySearchRecursive(nums, target, mid + 1, high);
96 | }
97 |
98 | // Target value is not present in the array
99 | return -1;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/BitonicArrayMaximum.java:
--------------------------------------------------------------------------------
1 | /**
2 | * BitonicArrayMaximum Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Find the maximum value in a given Bitonic array. An array is
7 | * considered bitonic if it is monotonically increasing and then monotonically decreasing.
8 | * Monotonically increasing or decreasing means that for any index i in the array arr[i] !=
9 | * arr[i+1].
10 | * @note Example
11 | * Input: [1, 3, 8, 12, 4, 2] Output: 12 Explanation: The maximum number in the input bitonic
12 | * array is 12.
13 | * @note Solution
14 | * A bitonic array is a sorted array; the only difference is that its first part is sorted in
15 | * ascending order and the second part is sorted in descending order. We can use a similar
16 | * approach as discussed in Order-agnostic Binary Search.
17 | * Since no two consecutive numbers are same (as the array is monotonically increasing or
18 | * decreasing), whenever we calculate the middle, we can compare the numbers pointed out by the
19 | * index middle and middle+1 to find if we are in the ascending or the descending part. So:
20 | * f arr[middle] > arr[middle + 1], we are in the second (descending) part of the bitonic
21 | * array. Therefore, our required number could either be pointed out by middle or will be before
22 | * middle. This means we will be doing: end = middle.
23 | * If arr[middle] < arr[middle + 1], we are in the first (ascending) part of the bitonic
24 | * array. Therefore, the required number will be after middle. This means we will be doing:
25 | * start = middle + 1.
26 | * We can break when start == end. Due to the two points mentioned above, both start and end
27 | * will be pointing at the maximum number of the bitonic array.
28 | * @note Time complexity - Since we are reducing the search range by half at every step, this means
29 | * that the time complexity of our algorithm will be O(logN) where N is the total elements in
30 | * the given array.
31 | *
32 | * @note Space complexity - The algorithm runs in constant space O(1).
33 | * @author David Kariuki
34 | * @since 24/8/2022
35 | */
36 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
37 |
38 | public class BitonicArrayMaximum {
39 |
40 | /**
41 | * Main method
42 | *
43 | * @param args - String[]
44 | */
45 | public static void main(String[] args) {
46 |
47 | System.out.println(BitonicArrayMaximum.findMax(new int[] {1, 3, 8, 12, 4, 2}));
48 | System.out.println(BitonicArrayMaximum.findMax(new int[] {3, 8, 3, 1}));
49 | System.out.println(BitonicArrayMaximum.findMax(new int[] {1, 3, 8, 12}));
50 | System.out.println(BitonicArrayMaximum.findMax(new int[] {10, 9, 8}));
51 | }
52 |
53 | /**
54 | * Method to find max in a bitonic array
55 | *
56 | * @param nums - int[]
57 | * @return int
58 | */
59 | public static int findMax(int[] nums) {
60 |
61 | int start = 0;
62 | int end = nums.length - 1;
63 |
64 | while (start < end) {
65 |
66 | int mid = start + ((end - start) / 2); // Calculate mid point
67 |
68 | if (nums[mid] > nums[mid + 1]) {
69 | end = mid;
70 | } else if (nums[mid] < nums[mid + 1]) {
71 | start = mid + 1;
72 | }
73 | }
74 |
75 | // At the end of the while loop, 'start == end'
76 | return nums[start];
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/FindLowOrHighIndexOfAnElementInSortedArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * FindLowOrHighIndexOfAnElementInSortedArray Class
3 | *
4 | *
5 | *
6 | * @question We’re given a sorted array of integers, nums, and an integer value, target. Return the
7 | * low and high index of the given target element. If the indexes are not found, return -1.
8 | * @note The array can contain multiple duplicates with length in millions.
9 | * @example int array -> {1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 20}
10 | * For target= 1: low = 0 and high = 0
11 | * For target= 2: low = 1 and high = 1
12 | * For target= 5: low = 2 and high = 9
13 | *
14 | * Linearly scanning the sorted array for low and high indices is highly inefficient since
15 | * our array size can be in the millions. Instead, we will use a slightly modified binary search
16 | * to find the low and high indices of a given target.
17 | * @author David Kariuki
18 | * @since /8/2022
19 | */
20 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
21 |
22 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
23 |
24 | @SuppressWarnings("ALL")
25 | public class FindLowOrHighIndexOfAnElementInSortedArray {
26 |
27 | /**
28 | * Main method
29 | *
30 | * @param args - String[]
31 | */
32 | public static void main(String[] args) {
33 |
34 | int[] arr =
35 | new int[] {1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 9};
36 |
37 | int target = 5;
38 |
39 | DataStructuresUtils.printOutArray(arr);
40 |
41 | System.out.println(
42 | "The low index of target : " + target + " is : " + findLowIndex(arr, target));
43 | System.out.println();
44 |
45 | System.out.println(
46 | "The high index of target : " + target + " is : " + findHighIndex(arr, target));
47 | System.out.println();
48 | }
49 |
50 | /**
51 | * Method to find low index
52 | *
53 | *
54 | *
55 | * @note Time complexity - Since we are using binary search, the time complexity is logarithmic,
56 | * O(logn). Even though we do the binary search twice, the asymptotic time complexity is still
57 | * O(logn).
58 | *
59 | * @note Space complexity - The space complexity is constant, O(1) O (1) , since no extra storage
60 | * is used.
61 | * @param nums - int[]
62 | * @param target - int
63 | * @return int
64 | */
65 | static int findLowIndex(int[] nums, int target) {
66 | int low = 0;
67 | int high = nums.length - 1;
68 | int mid = high / 2;
69 |
70 | while (low <= high) {
71 | int midElem = nums[mid];
72 |
73 | // Target value is less than the middle value
74 | if (midElem < target) {
75 | low = mid + 1;
76 | }
77 |
78 | // Target value is greater than or equal to the middle value
79 | else {
80 | high = mid - 1;
81 | }
82 |
83 | // Updating the mid value
84 | mid = low + (high - low) / 2;
85 | }
86 |
87 | if (low < nums.length && nums[low] == target) {
88 | return low;
89 | }
90 |
91 | return -1;
92 | }
93 |
94 | /**
95 | * Method to find high index
96 | *
97 | *
98 | *
99 | * @note Time complexity - Since we are using binary search, the time complexity is logarithmic,
100 | * O(logn). Even though we do the binary search twice, the asymptotic time complexity is still
101 | * O(logn).
102 | *
103 | * @note Space complexity - The space complexity is constant, O(1) O (1) , since no extra storage
104 | * is used.
105 | * @param nums - int[]
106 | * @param target - int
107 | * @return int
108 | */
109 | static int findHighIndex(int[] nums, int target) {
110 | int low = 0;
111 | int high = nums.length - 1;
112 | int mid = high / 2;
113 |
114 | while (low <= high) {
115 |
116 | int midElem = nums[mid];
117 |
118 | // Target value is less than or equal to the middle value
119 | if (midElem <= target) {
120 | low = mid + 1;
121 | }
122 |
123 | // Target value is greater than the middle value
124 | else {
125 | high = mid - 1;
126 | }
127 |
128 | // Updating the mid value
129 | mid = low + (high - low) / 2;
130 | }
131 |
132 | if (high == -1) {
133 | return high;
134 | }
135 |
136 | if (high < nums.length && nums[high] == target) {
137 | return high;
138 | }
139 |
140 | return -1;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/MoveAllZerosToTheBeginningOfTheArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MoveAllZerosToTheBeginningOfTheArray Class
3 | *
4 | *
5 | *
6 | * @question Move all zeros to the left of an array while maintaining its order.
7 | * @author David Kariuki
8 | * @since 18/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class MoveAllZerosToTheBeginningOfTheArray {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[][] numsList = {
24 | {1, 10, 20, 0, 59, 63, 0, 88, 0},
25 | {1, 0, 2, 3, 0},
26 | {0},
27 | {-1, 0, 0, -2, 9},
28 | {1, 2, 3, 4, 5},
29 | {2}
30 | };
31 |
32 | for (int i = 0; i < numsList.length; i++) {
33 | DataStructuresUtils.printOutArray(numsList[i], (i + 1) + ". Before list: ");
34 | moveZerosToLeft(numsList[i]);
35 | DataStructuresUtils.printOutArray(numsList[i], "After list:\t");
36 | System.out.println("-------------------------\n");
37 | }
38 | }
39 |
40 | /**
41 | * @explanation - Solution. We will use Read and Write pointers and start by pointing them to the
42 | * end of the array.
43 | * While moving the Read pointer towards the start of the array:
44 | * If the value at the Read pointer is 0, decrement the Read pointer. If the value at the
45 | * Read pointer is non-zero, set the value at the - Write pointer equal to the value at the
46 | * Read pointer, and decrement the - Write and Read pointers. Once, the Read pointer reaches
47 | * the 0th index, start assigning zeros to all the values from the - Write pointer back to the
48 | * 0th index.
49 | * @note Time complexity - The time complexity of this solution is O(n).
50 | *
51 | * @note Space complexity - The space complexity of this solution is O(1).
52 | */
53 | static void moveZerosToLeft(int[] nums) {
54 |
55 | // Initialize markers
56 | int writeIndex = nums.length - 1;
57 | int readIndex = nums.length - 1;
58 |
59 | // Iterate readIndex marker till the index is less than or equal to zero
60 | while (readIndex >= 0) {
61 | // Replacing write_index value with read_index value. This step moves
62 | // the next non-zero value "back" in the array, making space for the
63 | // zero at the head of the array
64 | if (nums[readIndex] != 0) {
65 | nums[writeIndex] = nums[readIndex];
66 | writeIndex--;
67 | }
68 |
69 | readIndex--;
70 | }
71 |
72 | // Replacing initial values with zeroes
73 | while (writeIndex >= 0) {
74 | nums[writeIndex] = 0;
75 | writeIndex--;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/OrderAgnosticBinarySearch.java:
--------------------------------------------------------------------------------
1 | /**
2 | * OrderAgnosticBinarySearch Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given a sorted array of numbers, find if a given number ‘key’ is
7 | * present in the array. Though we know that the array is sorted, we don’t know if it’s sorted
8 | * in ascending or descending order. You should assume that the array can have duplicates.
9 | * Write a function to return the index of the ‘key’ if it is present in the array, otherwise
10 | * return -1.
11 | * @note Solution - To make things simple, let’s first solve this problem assuming that the input
12 | * array is sorted in ascending order. Here are the set of steps for Binary Search:
13 | * Let’s assume start is pointing to the first index and end is pointing to the last index of
14 | * the input array (let’s call it arr).
15 | * This means: int start = 0; int end = arr.length - 1;
16 | * First, we will find the middle. middle = start + ((end - start) / 2)
17 | * Next, we will see if the ‘key’ is equal to the number at index middle. If it is equal we
18 | * return middle as the required index. If ‘key’ is not equal to number at index middle, we have
19 | * to check two things:
20 | * If (key < arr[middle]), then we can conclude that the key will be smaller than all the
21 | * numbers after index middle as the array is sorted in the ascending order. Hence, we can
22 | * reduce our search to end = mid - 1.
23 | * If (key > arr[middle]), then we can conclude that the key will be greater than all numbers
24 | * before index middle as the array is sorted in the ascending order. Hence, we can reduce our
25 | * search to start = mid + 1.
26 | * We will repeat steps 2-4 with new ranges of start to end. If at any time start becomes
27 | * greater than end, this means that we can’t find the ‘key’ in the input array and we must
28 | * return ‘-1’.
29 | *
30 | * If the array is sorted in the descending order, we have to update the step 4 above as:
31 | * If key > arr[middle], then we can conclude that the key will be greater than all numbers
32 | * after index middle as the array is sorted in the descending order. Hence, we can reduce our
33 | * search to end = mid - 1.
34 | * If key < arr[middle], then we can conclude that the key will be smaller than all the
35 | * numbers before index middle as the array is sorted in the descending order. Hence, we can
36 | * reduce our search to start = mid + 1.
37 | * Finally, how can we figure out the sort order of the input array? We can compare the
38 | * numbers pointed out by start and end index to find the sort order. If arr[start] < arr[end],
39 | * it means that the numbers are sorted in ascending order otherwise they are sorted in the
40 | * descending order.
41 | *
42 | * @note Time complexity - Since, we are reducing the search range by half at every step, this means
43 | * that the time complexity of our algorithm will be O(logN) where N is the total elements in
44 | * the given array.
45 | *
46 | * @note Space complexity - The algorithm runs in constant space O(1).
47 | * @author David Kariuki
48 | * @since 24/8/2022
49 | */
50 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
51 |
52 | public class OrderAgnosticBinarySearch {
53 |
54 | /**
55 | * Main method
56 | *
57 | * @param args - String[]
58 | */
59 | public static void main(String[] args) {
60 |
61 | System.out.println(OrderAgnosticBinarySearch.search(new int[] {4, 6, 10}, 10));
62 | System.out.println(OrderAgnosticBinarySearch.search(new int[] {1, 2, 3, 4, 5, 6, 7}, 5));
63 | System.out.println(OrderAgnosticBinarySearch.search(new int[] {10, 6, 4}, 10));
64 | System.out.println(OrderAgnosticBinarySearch.search(new int[] {10, 6, 4}, 4));
65 | }
66 |
67 | /** Method to search array and return index of key */
68 | public static int search(int[] nums, int key) {
69 |
70 | int start = 0; // Initialize start
71 | int end = nums.length - 1; // Initialize end
72 |
73 | // Check if array is ascending or descending
74 | boolean arrayIsAscending = nums[start] < nums[end];
75 |
76 | // Traverse array
77 | while (start <= end) {
78 |
79 | int mid = start + ((end - start) / 2);
80 |
81 | // Check if key is at the midpoint
82 | if (nums[mid] == key) {
83 | return mid;
84 | }
85 |
86 | if (arrayIsAscending) { // ascending order
87 |
88 | if (nums[mid] > key) {
89 | end = mid - 1; // The key can be in the first half
90 | } else if (nums[mid] < key) {
91 | start = mid + 1; // The key can be in the second half
92 | }
93 |
94 | } else { // Descending order
95 | if (nums[mid] > key) {
96 | start = mid + 1;
97 | } else if (nums[mid] < key) {
98 | end = mid - 1;
99 | }
100 | }
101 | }
102 |
103 | return -1;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/SearchRotatedArray_Iteratively.java:
--------------------------------------------------------------------------------
1 | /**
2 | * SearchRotatedArray_Iteratively Class
3 | *
4 | *
5 | *
6 | * @question Search for a given number in a sorted array that has been rotated by some arbitrary
7 | * number. We're given a sorted integer array, nums and an integer value, target. The array is
8 | * rotated by some arbitrary number. Search the target in this array. If the target does not
9 | * exist then return -1.
10 | * @author David Kariuki
11 | * @since 18/8/2022
12 | */
13 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
14 |
15 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
16 |
17 | public class SearchRotatedArray_Iteratively {
18 |
19 | /**
20 | * Main method
21 | *
22 | * @param args - String[]
23 | */
24 | public static void main(String[] args) {
25 |
26 | int[] targetList = {3, 6, 3, 6};
27 | int[][] numsList = {
28 | {6, 7, 1, 2, 3, 4, 5},
29 | {6, 7, 1, 2, 3, 4, 5},
30 | {4, 5, 6, 1, 2, 3},
31 | {4, 5, 6, 1, 2, 3}
32 | };
33 |
34 | for (int i = 0; i < targetList.length; i++) {
35 |
36 | System.out.println((i + 1) + ". Rotated array: "
37 | + DataStructuresUtils.arrayToString(numsList[i]));
38 | System.out.println(" target " + targetList[i] + " found at index "
39 | + binarySearchRotated(numsList[i], targetList[i]));
40 | System.out.println("--------------------------\n");
41 | }
42 | }
43 |
44 | /**
45 | * Method to perform binary search
46 | *
47 | *
48 | *
49 | * @note Time complexity - The time complexity of this solution is O(log n).
50 | * @note Space complexity - The space complexity of this solution is constant, O(1).
51 | * @param nums - int[]
52 | * @param target - int
53 | */
54 | public static int binarySearchRotated(int[] nums, int target) {
55 |
56 | int start = 0;
57 | int end = nums.length - 1;
58 |
59 | if (start > end) {
60 | return -1;
61 | }
62 |
63 | while (start <= end) {
64 |
65 | int mid = start + ((end - start) / 2);
66 |
67 | // Target value is present at the middle of the array
68 | if (target == nums[mid]) {
69 | return mid;
70 | }
71 |
72 | // Start to mid is sorted
73 | if (nums[start] <= nums[mid]) {
74 | if (nums[start] <= target && target < nums[mid]) {
75 | end = mid - 1;
76 | } else {
77 | start = mid + 1;
78 | }
79 | }
80 |
81 | // Mid to end is sorted
82 | else {
83 | if (nums[mid] < target && target <= nums[end]) {
84 | start = mid + 1;
85 | } else {
86 | end = mid - 1;
87 | }
88 | }
89 | }
90 | return -1;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/SearchRotatedArray_Recursive.java:
--------------------------------------------------------------------------------
1 | /**
2 | * SearchRotatedArray_Recursive Class
3 | *
4 | *
5 | *
6 | * @question Search for a given number in a sorted array that has been rotated by some arbitrary
7 | * number. We're given a sorted integer array, nums and an integer value, target. The array is
8 | * rotated by some arbitrary number. Search the target in this array. If the target does not
9 | * exist then return -1.
10 | * @author David Kariuki
11 | * @since 18/8/2022
12 | */
13 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
14 |
15 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
16 |
17 | public class SearchRotatedArray_Recursive {
18 |
19 | /**
20 | * Main method
21 | *
22 | * @param args - String[]
23 | */
24 | public static void main(String[] args) {
25 |
26 | int[] targetList = {3, 6, 3, 6};
27 | int[][] numsList = {
28 | {6, 7, 1, 2, 3, 4, 5}, {6, 7, 1, 2, 3, 4, 5}, {4, 5, 6, 1, 2, 3}, {4, 5, 6, 1, 2, 3}
29 | };
30 |
31 | for (int i = 0; i < targetList.length; i++) {
32 |
33 | System.out.println(
34 | (i + 1) + ". Rotated array: " + DataStructuresUtils.arrayToString(numsList[i]));
35 | System.out.println(
36 | " target "
37 | + targetList[i]
38 | + " found at index "
39 | + binarySearchRotated(numsList[i], targetList[i]));
40 | System.out.println("------------------\n");
41 | }
42 | }
43 |
44 | /**
45 | * Method to perform binary search
46 | *
47 | * @param nums - int[]
48 | * @param target - int
49 | */
50 | static int binarySearchRotated(int[] nums, int target) {
51 | return binarySearch(nums, 0, nums.length - 1, target);
52 | }
53 |
54 | /**
55 | * Method to perform binary search
56 | *
57 | *
58 | *
59 | * @note Time complexity - The time complexity of this solution is O(log n).
60 | * @note Space complexity - The space complexity of this solution is logarithmic, O(log n) .
61 | * @param nums - int[]
62 | * @param start - int
63 | * @param end - int
64 | * @param target - int
65 | */
66 | public static int binarySearch(int[] nums, int start, int end, int target) {
67 |
68 | if (start > end) {
69 | return -1;
70 | }
71 |
72 | int mid = start + ((end - start) / 2);
73 |
74 | // Target value is present at the middle of the array
75 | if (target == nums[mid]) {
76 | return mid;
77 | }
78 |
79 | // Start to mid is sorted
80 | if (nums[start] <= nums[mid]) {
81 | if (nums[start] <= target && target < nums[mid]) {
82 | binarySearch(nums, start, mid - 1, target);
83 | } else {
84 | binarySearch(nums, mid + 1, end, target);
85 | }
86 | }
87 |
88 | // Mid to end is sorted
89 | else {
90 | if (nums[mid] < target && target <= nums[end]) {
91 | binarySearch(nums, mid + 1, end, target);
92 | } else {
93 | binarySearch(nums, start, mid - 1, target);
94 | }
95 | }
96 |
97 | return -1;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/StockBuySellToMaximizeProfit.java:
--------------------------------------------------------------------------------
1 | /**
2 | * StockBuySellToMaximizeProfit Class
3 | *
4 | *
5 | *
6 | * @question Given a list of stock prices, find the maximum profit with a single buy or sell
7 | * activity.
8 | * We’re given an array of daily stock prices (integers for simplicity). Return the buying
9 | * and selling prices for making the maximum profit.
10 | * The values in the array represent the cost of stock each day. As we can buy and sell the
11 | * stock only once, we need to find the best buy and sell prices that maximize profit (or
12 | * minimized loss) over a given span of time.
13 | * We need to maximize the profit from a single buy and sell. If we can’t make any profit,
14 | * we’ll try to minimize the loss.
15 | * @author David Kariuki
16 | * @since 18/8/2022
17 | */
18 | package AceTheJavaCodingInterview.module2_data_structures.arrays.binary_search;
19 |
20 | import AceTheJavaCodingInterview.module2_data_structures.tuples.Tuple;
21 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
22 |
23 | @SuppressWarnings("UnusedAssignment")
24 | public class StockBuySellToMaximizeProfit {
25 |
26 | /**
27 | * Main method
28 | *
29 | * @param args - String[]
30 | */
31 | public static void main(String[] args) {
32 |
33 | int[][] stockNums = {
34 | {1, 2, 3, 4, 3, 2, 1, 2, 5}, {8, 6, 5, 4, 3, 2, 1}, {12, 30, 40, 90, 110}, {2}
35 | };
36 |
37 | for (int i = 0; i < stockNums.length; i++) {
38 | Tuple
54 | *
55 | * @note Time complexity - The time complexity of this solution is O(n).
56 | * @note Space complexity - The space complexity of this algorithm is O(1).
57 | */
58 | @SuppressWarnings("Convert2Diamond")
59 | public static Tuple
5 | *
6 | * @note Given an array, can you re-arrange the elements such that the first position will have the
7 | * largest number, the second will have the smallest, the third will have the second-largest,
8 | * and so on.
9 | * @author David Kariuki
10 | * @since 16/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
15 |
16 | public class CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_1 {
17 |
18 | /**
19 | * Main method
20 | *
21 | * @param args - String[]
22 | */
23 | public static void main(String[] args) {
24 | int[] arr = {1, 2, 3, 4, 5, 6};
25 | System.out.print("Array before min/max: ");
26 |
27 | System.out.print(DataStructuresUtils.arrayToString(arr));
28 | System.out.println();
29 |
30 | maxMin(arr);
31 |
32 | System.out.print("Array after min/max: ");
33 | for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + " ");
34 | System.out.println();
35 | }
36 |
37 | /**
38 | * Method to find max/min
39 | *
40 | *
41 | *
42 | * @note Time Complexity - The time complexity of this problem is O(n)
43 | * as the array is iterated over once.
44 | * @param arr - int[]
45 | */
46 | @SuppressWarnings("ManualArrayCopy")
47 | static void maxMin(int[] arr) {
48 |
49 | // Create a result array to hold re-arranged version of given arr
50 | int[] result = new int[arr.length];
51 |
52 | int pointerSmall = 0; // PointerSmall => Start of arr
53 | int pointerLarge = arr.length - 1; // PointerLarge => End of arr
54 |
55 | // Flag which will help in switching between two pointers
56 | boolean switchPointer = true;
57 |
58 | for (int i = 0; i < arr.length; i++) {
59 |
60 | if (switchPointer) {
61 | result[i] = arr[pointerLarge--]; // Copy large values
62 | } else {
63 | result[i] = arr[pointerSmall++]; // Copy small values
64 | }
65 |
66 | switchPointer = !switchPointer; // Switching between small and large
67 | }
68 |
69 | // Copy new array into old array
70 | for (int j = 0; j < arr.length; j++) {
71 | arr[j] = result[j]; // Copying to original array
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_2 Class
3 | *
4 | *
5 | *
6 | * @note Given an array, can you re-arrange the elements such that the first position will have the
7 | * largest number, the second will have the smallest, the third will have the second-largest,
8 | * and so on.
9 | * @author David Kariuki
10 | * @since 16/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | public class CH10_RearrangeSortedArrayInMaxOrMinForm_SOL_2 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
24 | System.out.print("Array before min/max: ");
25 | for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + " ");
26 | System.out.println();
27 |
28 | maxMin(arr);
29 |
30 | System.out.print("Array after min/max: ");
31 | for (int i = 0; i < arr.length; i++) System.out.print(arr[i] + " ");
32 | System.out.println();
33 | }
34 |
35 | /**
36 | * Method to find max/min
37 | *
38 | *
39 | *
40 | * @note Time Complexity - The time complexity of this solution is in O(n). The space complexity
41 | * is constant.
42 | * @param arr - int[]
43 | */
44 | static void maxMin(int[] arr) {
45 |
46 | int maxIdx = arr.length - 1;
47 | int minIdx = 0;
48 |
49 | // Store any element that is greater than the maximum element in the array
50 | int maxElem = arr[maxIdx] + 1;
51 |
52 | // Traverse array
53 | for (int i = 0; i < arr.length; i++) {
54 |
55 | // at even indices we will store maximum elements
56 | if (i % 2 == 0) {
57 |
58 | arr[i] += (arr[maxIdx] % maxElem) * maxElem;
59 | maxIdx -= 1;
60 |
61 | } else { // at odd indices we will store minimum elements
62 |
63 | arr[i] += (arr[minIdx] % maxElem) * maxElem;
64 | minIdx += 1;
65 | }
66 | }
67 | // dividing with maxElem to get original values.
68 | for (int i = 0; i < arr.length; i++) {
69 | arr[i] = arr[i] / maxElem;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH11_FindTheSumOfMaximumSumSubarray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH11_FindTheSumOfMaximumSumSubarray Class
3 | *
4 | *
5 | *
6 | * @note Given an array, find the sum of contiguous subarray with the largest sum. Given an unsorted
7 | * array A, the maximum sum sub-array is the sub-array (contiguous elements) from A, for which
8 | * the sum of the elements is maximum. In this challenge, we want to find the sum of the maximum
9 | * sum sub-array. The array might have negative integers in any position, so we have to cater to
10 | * those negative integers while choosing the contiguous subarray with the largest positive
11 | * values.
12 | *
13 | * @note Kadane's Algorithm - The basic idea of Kadane’s algorithm is to scan the entire array and
14 | * at each position find the maximum sum of the subarray ending there. This is achieved by
15 | * keeping a currMax for the current array index and a globalMax.
16 | * @author David Kariuki
17 | * @since 17/8/2022
18 | */
19 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
20 |
21 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
22 |
23 | public class CH11_FindTheSumOfMaximumSumSubarray {
24 |
25 | /**
26 | * Main method
27 | *
28 | * @param args - String[]
29 | */
30 | public static void main(String[] args) {
31 |
32 | int[] arr1 = {1, 7, -2, -5, 10, -1};
33 |
34 | System.out.println("Array: " + DataStructuresUtils.arrayToString(arr1));
35 | System.out.println("Sum: " + findMaxSumSubArray(arr1));
36 | }
37 |
38 | /**
39 | * Method to find the sum of maximum sum subarray
40 | *
41 | *
42 | *
43 | * @note Runtime complexity - The runtime complexity of this solution is linear, O(n).
44 | *
45 | * @note Space complexity - The space complexity of this solution is constant, O(1).
46 | * @param arr - int[]
47 | */
48 | public static int findMaxSumSubArray(int[] arr) {
49 |
50 | if (arr.length < 1) {
51 | return 0;
52 | }
53 |
54 | int currMax = arr[0];
55 | int globalMax = arr[0];
56 |
57 | // Traverse array
58 | for (int i = 1; i < arr.length; i++) {
59 |
60 | // Check if current max is less than 0 to re-assign
61 | if (currMax < 0) {
62 | currMax = arr[i]; // Re-assign with current element at i
63 | } else {
64 | currMax += arr[i]; // Increment
65 | }
66 |
67 | // Check if global max is less that current max
68 | if (globalMax < currMax) {
69 | globalMax = currMax;
70 | }
71 | }
72 | return globalMax;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH1_RemoveEvenFromArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH1_RemoveEvenFromArray Class
3 | *
4 | *
5 | *
6 | * @note Challenge 1: Remove Even Integers from an Array.
7 | * Given an array of size n, remove all even integers from it.
8 | * @author David Kariuki
9 | * @since 14/8/2022
10 | */
11 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
12 |
13 | public class CH1_RemoveEvenFromArray {
14 |
15 | /**
16 | * Method to remove even numbers from array
17 | *
18 | * @param arr - int[]
19 | */
20 | public static int[] removeEven(int[] arr) {
21 | int oddElements = 0;
22 |
23 | // Find number of odd elements in arr
24 | for (int i = 0; i < arr.length; i++) {
25 | if (arr[i] % 2 != 0) {
26 | oddElements++;
27 | }
28 | }
29 |
30 | // Create result array with the size equal to the number of odd elements in arr
31 | int[] result = new int[oddElements];
32 | int result_index = 0;
33 |
34 | // Put odd values from arr to the resulted array
35 | for (int i = 0; i < arr.length; i++) {
36 | if (arr[i] % 2 != 0) {
37 | result[result_index++] = arr[i];
38 | }
39 | } // end of for loop
40 |
41 | return result;
42 | } // end of removeEven
43 |
44 | /**
45 | * Main method
46 | *
47 | * @param args - String[]
48 | */
49 | public static void main(String[] args) {
50 |
51 | int size = 10;
52 | int[] arr = new int[size]; // declaration and instantiation
53 |
54 | System.out.print("Before removing Even Numbers: ");
55 | for (int i = 0; i < arr.length; i++) {
56 |
57 | arr[i] = i; // assigning values
58 | System.out.print(arr[i] + " ");
59 | }
60 |
61 | System.out.println();
62 |
63 | int[] newArr = removeEven(arr); // calling removeEven
64 |
65 | System.out.print("After removing Even Numbers: ");
66 | for (int i = 0; i < newArr.length; i++) {
67 | System.out.print(newArr[i] + " "); // Prinitng array
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH2_MergeTwoSortedArrays.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH2_MergeTwoSortedArrays Class
3 | *
4 | *
5 | *
6 | * @note Challenge 2: Merge Two Sorted Arrays
7 | * Given two sorted arrays, merge them into one array, which should also
8 | * be sorted.
9 | * @author David Kariuki
10 | * @since 14/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | public class CH2_MergeTwoSortedArrays {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr1 = {1, 12, 14, 17, 23};
24 | int[] arr2 = {11, 19, 27};
25 |
26 | int[] resultantArray = mergeArrays(arr1, arr2); // calling mergeArrays
27 |
28 | System.out.print("Arrays after merging: ");
29 | for (int i = 0; i < arr1.length + arr2.length; i++) {
30 | System.out.print(resultantArray[i] + " ");
31 | }
32 | }
33 |
34 | /**
35 | * Method to remove even numbers from array
36 | *
37 | * The time complexity for this algorithm is O(n+m), where n and m are the * sizes of arr1 and
38 | * arr2, respectively. This is because both arrays are iterated over once.
39 | *
40 | * @param arr1 - Array1
41 | * @param arr2 - Array2
42 | */
43 | public static int[] mergeArrays(int[] arr1, int[] arr2) {
44 |
45 | int arr1Length = arr1.length;
46 | int arr2Length = arr2.length;
47 |
48 | int[] mergedArray = new int[(arr1Length + arr2Length)];
49 |
50 | int i = 0, j = 0, k = 0;
51 |
52 | // Traverse both arrays
53 | while (i < arr1Length && j < arr2Length) {
54 |
55 | // Check if current element of first array is smaller than current
56 | // element of second array. If yes, store first array element and
57 | // increment first array index. Otherwise, do same with second array
58 | if (arr1[i] < arr2[j]) {
59 | mergedArray[k++] = arr1[i++]; // Add element from array 1
60 | } else if (arr2[j] < arr1[i]) {
61 | mergedArray[k++] = arr2[j++]; // Add element from array 2
62 | }
63 | }
64 |
65 | // Store the remaining elements of 1st array
66 | while (i < arr1Length) {
67 | mergedArray[k++] = arr1[i++];
68 | }
69 |
70 | // Store the remaining elements of 2nd array
71 | while (j < arr2Length) {
72 | mergedArray[k++] = arr2[j++];
73 | }
74 |
75 | return mergedArray;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH3_FindTwoNoAddingUpToN_Sol_1.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH3_FindTwoNoAddingUpToN_Sol_1 Class
3 | *
4 | *
5 | *
6 | * @note Challenge 2: Merge Two Sorted Arrays
7 | * Given an array and a number "n", find two numbers from the array that
8 | * sums up to "n".
9 | * @author David Kariuki
10 | * @since 14/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | public class CH3_FindTwoNoAddingUpToN_Sol_1 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int n = 9;
24 | int[] arr1 = {2, 4, 5, 7, 8};
25 |
26 | int[] arr2 = findSum(arr1, n);
27 | int num1 = arr2[0];
28 | int num2 = arr2[1];
29 |
30 | if ((num1 + num2) != n) System.out.println("Not Found");
31 | else {
32 | System.out.println("Number 1 = " + num1);
33 | System.out.println("Number 2 = " + num2);
34 | System.out.println("Sum = " + (n));
35 | }
36 | }
37 |
38 | /**
39 | * Method to find the sum of two index elements adding up to n and the elements
40 | *
41 | * @param arr - int[]
42 | * @param n - Target sum
43 | */
44 | public static int[] findSum(int[] arr, int n) {
45 |
46 | int[] result = new int[2]; // to store the pair of values.
47 |
48 | for (int i = 0; i < arr.length; i++) { // traverse arr
49 | for (int j = i + 1; j < arr.length; j++) { // traverse arr again
50 | if (arr[i] + arr[j] == n) { // find where sum is equal to n
51 | result[0] = arr[i];
52 | result[1] = arr[j];
53 | return result; // return the pair of numbers
54 | }
55 | }
56 | }
57 | return arr;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH3_FindTwoNoAddingUpToN_Sol_2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH3_FindTwoNoAddingUpToN_Sol_2 Class
3 | *
4 | *
5 | *
6 | * @note Challenge 2: Merge Two Sorted Arrays
7 | * Given an array and a number "n", find two numbers from the array that
8 | * sums up to "n".
9 | * @author David Kariuki
10 | * @since 14/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | public class CH3_FindTwoNoAddingUpToN_Sol_2 {
15 |
16 | /**
17 | * Helper Function to sort given Array (Quick Sort)
18 | *
19 | * @param arr - int[]
20 | * @param low - int
21 | * @param high - int
22 | */
23 | public static int partition(int[] arr, int low, int high) {
24 | int pivot = arr[high];
25 | int i = (low - 1); // index of smaller element
26 | for (int j = low; j < high; j++) {
27 | // If current element is <= to pivot
28 | if (arr[j] <= pivot) {
29 | i++;
30 |
31 | // swap arr[i] and arr[j]
32 | int temp = arr[i];
33 | arr[i] = arr[j];
34 | arr[j] = temp;
35 | }
36 | }
37 |
38 | // swap arr[i+1] and arr[high] (or pivot)
39 | int temp = arr[i + 1];
40 | arr[i + 1] = arr[high];
41 | arr[high] = temp;
42 |
43 | return i + 1;
44 | }
45 |
46 | /**
47 | * @param arr - int[]
48 | * @param low - int
49 | * @param high - high
50 | */
51 | public static void sort(int[] arr, int low, int high) {
52 | if (low < high) {
53 | int pi = partition(arr, low, high);
54 | sort(arr, low, pi - 1);
55 | sort(arr, pi + 1, high);
56 | }
57 | }
58 |
59 | /**
60 | * Return 2 elements of arr that sum to the given value
61 | *
62 | * @param arr - int[]
63 | * @param n n
64 | */
65 | public static int[] findSum(int[] arr, int n) {
66 |
67 | // Helper sort function that uses the Quicksort Algorithm
68 | sort(arr, 0, arr.length - 1); // Sort the array in Ascending Order
69 |
70 | int Pointer1 = 0; // Pointer 1 -> At Start
71 | int Pointer2 = arr.length - 1; // Pointer 2 -> At End
72 |
73 | int[] result = new int[2];
74 | int sum;
75 |
76 | while (Pointer1 != Pointer2) {
77 |
78 | sum = arr[Pointer1] + arr[Pointer2]; // Calulate Sum of Pointer 1 and 2
79 |
80 | if (sum < n) Pointer1++; // if sum is less than given value => Move Pointer 1 to Right
81 | else if (sum > n) Pointer2--;
82 | else {
83 | result[0] = arr[Pointer1];
84 | result[1] = arr[Pointer2];
85 | return result; // containing 2 number
86 | }
87 | }
88 | return arr;
89 | }
90 |
91 | /**
92 | * Main method
93 | *
94 | * @param args - String[]
95 | */
96 | public static void main(String[] args) {
97 |
98 | int n = 9;
99 | int[] arr1 = {1, 2, 3, 4, 5};
100 | int[] arr2 = findSum(arr1, n);
101 | int num1 = arr2[0];
102 | int num2 = arr2[1];
103 |
104 | if ((num1 + num2) != n) System.out.println("Not Found");
105 | else {
106 | System.out.println("Number 1 = " + num1);
107 | System.out.println("Number 2 = " + num2);
108 | System.out.println("Sum = " + (n));
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH4_ArrayOFProductsOfAllElementsExceptItself.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH4_ArrayOFProductsOfAllElementsExceptItself Class
3 | *
4 | *
5 | *
6 | * @note Given an array, return an array where each index stores the product of all numbers except
7 | * the number on the index itself.
8 | * @author David Kariuki
9 | * @since 16/8/2022
10 | */
11 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
12 |
13 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
14 |
15 | public class CH4_ArrayOFProductsOfAllElementsExceptItself {
16 |
17 | /**
18 | * Main method
19 | *
20 | * @param args - String[]
21 | */
22 | public static void main(String[] args) {
23 |
24 | int[] arr = {-1, 2, -3, 4, -5};
25 |
26 | System.out.println("Array before product: " + DataStructuresUtils.arrayToString(arr));
27 |
28 | int[] prodArray = findProduct(arr);
29 |
30 | System.out.println("Array after product: " + DataStructuresUtils.arrayToString(prodArray));
31 | }
32 |
33 | /**
34 | * Find product
35 | *
36 | * Time complexity is O(n) Space complexity is O(n) Auxiliary Space Used is O(1)
37 | *
38 | * @param arr - int[]
39 | */
40 | public static int[] findProduct(int[] arr) {
41 |
42 | int n = arr.length;
43 | int i, temp = 1;
44 |
45 | // Allocation of result array
46 | int[] result = new int[n];
47 |
48 | // Product of elements on left side excluding arr[i]
49 | for (i = 0; i < n; i++) {
50 | System.out.println(
51 | "1.--- i : "
52 | + i
53 | + " temp : "
54 | + temp
55 | + " arr[i] :"
56 | + " "
57 | + arr[i]
58 | + " result[i] : "
59 | + result[i]);
60 | result[i] = temp;
61 | temp *= arr[i];
62 | }
63 |
64 | System.out.println("\n");
65 |
66 | // Initializing temp to 1 for product on right side
67 | temp = 1;
68 |
69 | // Product of elements on right side excluding arr[i]
70 | for (i = n - 1; i >= 0; i--) {
71 | System.out.println(
72 | "2.--- i : "
73 | + i
74 | + " temp : "
75 | + temp
76 | + " arr[i] :"
77 | + " "
78 | + arr[i]
79 | + " result[i] : "
80 | + result[i]);
81 | result[i] *= temp;
82 | temp *= arr[i];
83 | }
84 |
85 | return result;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH5_FindMinimumValueInArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH5_FindMinimumValueInArray Class
3 | *
4 | *
5 | *
6 | * @note Given an array of size "n", can you find the minimum value in the array?
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class CH5_FindMinimumValueInArray {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = new int[] {30, 43, 55, 32, 12, 23, 4, 21, 21, 55, 67, 90, 32, 21};
24 |
25 | System.out.println(
26 | "Minimum in array : "
27 | + DataStructuresUtils.arrayToString(arr)
28 | + " "
29 | + "is : "
30 | + findMinimum(arr));
31 | }
32 |
33 | /**
34 | * Method to find minimum
35 | *
36 | *
37 | *
38 | * @note Time Complexity - Since the entire list is iterated over once, this algorithm is in
39 | * linear time - O(n)
40 | * @param arr - int[]
41 | */
42 | public static int findMinimum(int[] arr) {
43 |
44 | int minimum = arr[0];
45 |
46 | // At every Index compare its value with minimum and if it is less, then
47 | // make that index value new minimum value
48 | for (int i = 0; i < arr.length; i++) {
49 | // Check if element at current index is smaller than set minimum
50 | if (arr[i] < minimum) {
51 | minimum = arr[i]; // Assign new minimum
52 | }
53 | }
54 |
55 | return minimum;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH6_FindFirstNonRepeatingIntegerInArray.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH6_FindFirstNonRepeatingIntegerInArray Class
3 | *
4 | *
5 | *
6 | * @note Given an array, find the first integer, which is unique in the array.
7 | * Unique means the number does not repeat and appears only once in the
8 | * whole array.
9 | * @author David Kariuki
10 | * @since 16/8/2022
11 | */
12 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
13 |
14 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
15 |
16 | public class CH6_FindFirstNonRepeatingIntegerInArray {
17 |
18 | /**
19 | * Main method
20 | *
21 | * @param args - String[]
22 | */
23 | public static void main(String[] args) {
24 |
25 | int[] arr = {2, 54, 7, 2, 6, 54};
26 |
27 | System.out.println("Array: " + DataStructuresUtils.arrayToString(arr));
28 |
29 | int unique = findFirstUnique(arr);
30 | System.out.print("First Unique in an Array: " + unique);
31 | }
32 |
33 | /**
34 | * Method to find first unique element
35 | *
36 | *
37 | *
38 | * @note The time complexity of this solution is O(n^2) since the entire list is iterated for each
39 | * element n*n times.
40 | * @param arr - int[]
41 | */
42 | public static int findFirstUnique(int[] arr) {
43 |
44 | // Inside Inner Loop Check Each index of outerLoop If it is repeated in
45 | // array. If it's not repeated then return this as first unique Integer
46 | boolean numRepeated = false;
47 |
48 | // Traverse array
49 | for (int i = 0; i < arr.length; i++) {
50 |
51 | // Traverse array
52 | for (int j = 0; j < arr.length; j++) {
53 |
54 | if (i != j) {
55 | if (arr[i] == arr[j]) {
56 | numRepeated = true;
57 | break;
58 | } else {
59 | numRepeated = false;
60 | }
61 | }
62 | }
63 |
64 | if (!numRepeated) {
65 | return arr[i];
66 | }
67 | }
68 |
69 | return -1;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH7_FindSecondMaximumValueInArray_Sol_1.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH7_FindSecondMaximumValueInArray_Sol_1 Class
3 | *
4 | *
5 | *
6 | * @note Given an array of size n, can you find the second maximum element in the array?
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class CH7_FindSecondMaximumValueInArray_Sol_1 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = {-2, -33, -10, -456};
24 |
25 | System.out.println("Array: " + DataStructuresUtils.arrayToString(arr));
26 |
27 | int secMax = findSecondMaximum(arr);
28 |
29 | System.out.println("Second maximum: " + secMax);
30 | }
31 |
32 | /**
33 | * Method to find second maximum number in an int[] arr
34 | *
35 | *
36 | *
37 | * @note We traverse the array twice. In the first traversal, we find the maximum element. In the
38 | * second traversal, find the greatest element less than the element obtained in the first
39 | * traversal.
40 | *
41 | * @note Time Complexity - The time complexity of the solution is in O(n)
42 | * since the array is traversed twice but in separate loops. Which means
43 | * O(n+ n) => O(n)
44 | * @param arr - int[] arr
45 | */
46 | public static int findSecondMaximum(int[] arr) {
47 |
48 | int max = Integer.MIN_VALUE;
49 | int secondMax = Integer.MIN_VALUE;
50 |
51 | // Find the maximum value in the array by comparing each index with max
52 | // If an element is greater than max then update max to be equal to it
53 | for (int i = 0; i < arr.length; i++) {
54 | if (arr[i] > max) {
55 | max = arr[i];
56 | }
57 | }
58 |
59 | // Find the second maximum value by comparing each index with secondmax
60 | // If an element is greater than secondmax and not equal to previously
61 | // calculated max, then update secondmax to be equal to that element.
62 | for (int i = 0; i < arr.length; i++) {
63 | if ((arr[i] > secondMax) && (arr[i] < max)) {
64 | secondMax = arr[i];
65 | }
66 | }
67 |
68 | return secondMax;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH7_FindSecondMaximumValueInArray_Sol_2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH7_FindSecondMaximumValueInArray_Sol_2 Class
3 | *
4 | *
5 | *
6 | * @note Given an array of size n, can you find the second maximum element in the array?
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class CH7_FindSecondMaximumValueInArray_Sol_2 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = {-2, -33, -10, -456};
24 |
25 | System.out.println("Array: " + DataStructuresUtils.arrayToString(arr));
26 |
27 | int secMax = findSecondMaximum(arr);
28 |
29 | System.out.println("Second maximum: " + secMax);
30 | }
31 |
32 | /**
33 | * Method to find second maximum number in an int[] arr
34 | *
35 | *
36 | *
37 | * @note Time Complexity - This solution is in O(n) since the list is traversed once only.
38 | * @param arr - int[] arr
39 | */
40 | public static int findSecondMaximum(int[] arr) {
41 |
42 | int max = Integer.MIN_VALUE;
43 | int secondMax = Integer.MIN_VALUE;
44 |
45 | // Keep track of Maximum value, whenever the value at an array index is greater
46 | // than current Maximum value then make that max value 2nd max value and
47 | // make that index value maximum value
48 | for (int i = 0; i < arr.length; i++) {
49 | if (arr[i] > max) {
50 | secondMax = max;
51 | max = arr[i];
52 | } else if (arr[i] > secondMax && arr[i] != max) {
53 | secondMax = arr[i];
54 | }
55 | }
56 |
57 | return secondMax;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH8_RightRotateTheArrayByOneIndex.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH8_RightRotateTheArrayByOneIndex Class
3 | *
4 | *
5 | *
6 | * @note Given an array, can you rotate its elements once from right to left?
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | public class CH8_RightRotateTheArrayByOneIndex {
13 |
14 | /**
15 | * Main method
16 | *
17 | * @param args - String[]
18 | */
19 | public static void main(String[] args) {
20 | int[] arr = {3, 6, 1, 8, 4, 2};
21 |
22 | System.out.print("Array before rotation: ");
23 | for (int i = 0; i < arr.length; i++) {
24 | System.out.print(arr[i] + " ");
25 | }
26 | System.out.println();
27 |
28 | rotateArray(arr);
29 |
30 | System.out.print("Array after rotation: ");
31 | for (int i = 0; i < arr.length; i++) {
32 | System.out.print(arr[i] + " ");
33 | }
34 | }
35 |
36 | /**
37 | * Method to rotate an int array
38 | *
39 | *
40 | *
41 | * @note Time Complexity# Since the entire array is iterated over once, the time complexity of
42 | * this solution is O(n).
43 | * @param arr - int[]
44 | */
45 | @SuppressWarnings("ManualArrayCopy")
46 | public static void rotateArray(int[] arr) {
47 |
48 | int lastElement = arr[arr.length - 1]; // get last element
49 |
50 | for (int i = arr.length - 1; i > 0; i--) {
51 | arr[i] = arr[i - 1];
52 | }
53 |
54 | arr[0] = lastElement;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH9_ReArrangePositiveAndNegativeValues_SOL_1.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH9_ReArrangePositiveAndNegativeValues_SOL_1 Class
3 | *
4 | *
5 | *
6 | * @note
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class CH9_ReArrangePositiveAndNegativeValues_SOL_1 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = {10, -1, 20, 4, 5, -9, -6};
24 |
25 | System.out.println("Array before re-arranging : "
26 | + DataStructuresUtils.arrayToString(arr));
27 |
28 | arr = reArrange(arr);
29 |
30 | System.out.println("Array after re-arranging : "
31 | + DataStructuresUtils.arrayToString(arr));
32 | }
33 |
34 | static int[] reArrange(int[] arr) {
35 |
36 | int[] newArray = new int[arr.length];
37 |
38 | int j = 0;
39 | // Loop to get negatives
40 | for (int i = 0; i < arr.length; i++) {
41 | if (arr[i] < 0) {
42 | newArray[j++] = arr[i];
43 | }
44 | }
45 |
46 | // Loop to get positives
47 | for (int i = 0; i < arr.length; i++) {
48 | if (arr[i] > 0) {
49 | newArray[j++] = arr[i];
50 | }
51 | }
52 |
53 | return newArray;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/challenges/CH9_ReArrangePositiveAndNegativeValues_SOL_2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CH9_ReArrangePositiveAndNegativeValues_SOL_2 Class
3 | *
4 | *
5 | *
6 | * @note
7 | * @author David Kariuki
8 | * @since 16/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.arrays.challenges;
11 |
12 | import AceTheJavaCodingInterview.module2_data_structures.utils.DataStructuresUtils;
13 |
14 | public class CH9_ReArrangePositiveAndNegativeValues_SOL_2 {
15 |
16 | /**
17 | * Main method
18 | *
19 | * @param args - String[]
20 | */
21 | public static void main(String[] args) {
22 |
23 | int[] arr = {-50, -1, 20, 4, 5, -9, -6};
24 |
25 | System.out.println("Array before re-arranging : "
26 | + DataStructuresUtils.arrayToString(arr));
27 |
28 | reArrange(arr);
29 |
30 | System.out.println("Array after re-arranging : "
31 | + DataStructuresUtils.arrayToString(arr));
32 | }
33 |
34 | static void reArrange(int[] arr) {
35 |
36 | int j = 0;
37 | for (int i = 0; i < arr.length; i++) {
38 | if (arr[i] < 0) { // if negative number found
39 | if (i != j) {
40 | int temp = arr[i];
41 | arr[i] = arr[j]; // Swapping with leftmost positive
42 | arr[j] = temp;
43 | }
44 | j++;
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/sorting/CyclicSortEasy.java:
--------------------------------------------------------------------------------
1 | /**
2 | * CyclicSortEasy Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - We are given an array containing n objects. Each object, when
7 | * created, was assigned a unique number from the range 1 to n based on their creation sequence.
8 | * This means that the object with sequence number 3 was created just before the object with
9 | * sequence number 4.
10 | * Write a function to sort the objects in-place on their creation sequence number in O(n)
11 | * and without using any extra space. For simplicity, let’s assume we are passed an integer
12 | * array containing only the sequence numbers, though each number is actually an object.
13 | *
14 | * @note Solution - As we know, the input array contains numbers from the range 1 to n. We can use
15 | * this fact to devise an efficient way to sort the numbers. Since all numbers are unique, we
16 | * can try placing each number at its correct place, i.e., placing 1 at index ‘0’, placing 2 at
17 | * index ‘1’, and so on.
18 | * To place a number (or an object in general) at its correct index, we first need to find
19 | * that number. If we first find a number and then place it at its correct place, it will take
20 | * us O(N^2), which is not acceptable.
21 | * Instead, what if we iterate the array one number at a time, and if the current number we
22 | * are iterating is not at the correct index, we swap it with the number at its correct index.
23 | * This way, we will go through all numbers and place them at their correct indices, hence,
24 | * sorting the whole array.
25 | *
26 | * @note Time complexity - The time complexity of the below algorithm is O(n). Although we are not
27 | * incrementing the index i when swapping the numbers, this will result in more than n
28 | * iterations of the loop, but in the worst-case scenario, the while loop will swap a total of
29 | * n-1 numbers, and once a number is at its correct index, we will move on to the next number by
30 | * incrementing i. So overall, our algorithm will take O(n) + O(n-1) which is asymptotically
31 | * equivalent to O(n).
32 | *
33 | * @note Space complexity - The algorithm runs in constant space O(1).
34 | * @author David Kariuki
35 | * @since 23/8/2022
36 | */
37 | package AceTheJavaCodingInterview.module2_data_structures.arrays.sorting;
38 |
39 | public class CyclicSortEasy {
40 |
41 | /**
42 | * Main method
43 | *
44 | * @param args - String[]
45 | */
46 | public static void main(String[] args) {
47 |
48 | int[] arr = new int[] {3, 1, 5, 4, 2};
49 | CyclicSortEasy.sort(arr);
50 | for (int num : arr) System.out.print(num + " ");
51 | System.out.println();
52 |
53 | arr = new int[] {2, 6, 4, 3, 1, 5};
54 | CyclicSortEasy.sort(arr);
55 | for (int num : arr) System.out.print(num + " ");
56 | System.out.println();
57 |
58 | arr = new int[] {1, 5, 6, 4, 3, 2};
59 | CyclicSortEasy.sort(arr);
60 | for (int num : arr) System.out.print(num + " ");
61 | System.out.println();
62 | }
63 |
64 | /**
65 | * Method to sort int[]
66 | *
67 | * @param nums - int[]
68 | */
69 | public static void sort(int[] nums) {
70 |
71 | int i = 0;
72 |
73 | while (i < nums.length) {
74 | int j = nums[i] - 1;
75 |
76 | if (nums[i] != nums[j]) {
77 | swap(nums, i, j);
78 | } else {
79 | i++;
80 | }
81 | }
82 | }
83 |
84 | /**
85 | * Methods to swap array elements
86 | *
87 | * @param arr - int[]
88 | * @param i - int
89 | * @param j - int
90 | */
91 | public static void swap(int[] arr, int i, int j) {
92 | int temp = arr[i];
93 | arr[i] = arr[j];
94 | arr[j] = temp;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/sorting/QuicksortAlgorithm.java:
--------------------------------------------------------------------------------
1 | /**
2 | * QuicksortAlgorithm Class
3 | *
4 | *
5 | *
6 | * @question Given an integer array, sort it in ascending order using quicksort.
7 | * @note Solution Here is an overview of how the quicksort algorithm works:
8 | * Select a pivot element from the array to divide it into two parts. We pick the first
9 | * element as the pivot if we follow Hoare’s algorithm. Another common approach is to select a
10 | * random element as the pivot.
11 | * Reorder the array by comparing elements with the pivot element such that smaller values
12 | * end up on the left side and larger values end up on the right side of the pivot.
13 | * Now, the pivot element is in its correct sorted position. By applying the above steps, we
14 | * can recursively sort the sublists on the right and left sides of the pivot.
15 | * @note Time complexity - The time complexity of this solution is linearithmic, O(n logn).
16 | * @note Space complexity - The space complexity of this solution is logarithmic, O(logn), because
17 | * it consumes memory on the stack.
18 | * @author David Kariuki
19 | * @since 23/8/2022
20 | */
21 | package AceTheJavaCodingInterview.module2_data_structures.arrays.sorting;
22 |
23 | import java.util.Arrays;
24 |
25 | public class QuicksortAlgorithm {
26 |
27 | /**
28 | * Main method
29 | *
30 | * @param args - String[]
31 | */
32 | public static void main(String[] args) {
33 |
34 | int[][] numsList = {
35 | {55, 23, 26, 2, 18, 78, 23, 8, 2, 3}, {1}, {9, 8, 7, 2, 3, 1}, {10, 20, 30, -1, -2}
36 | };
37 |
38 | for (int i = 0; i < numsList.length; i++) {
39 |
40 | System.out.println((i + 1) + ". Before Sorting");
41 | System.out.println(" " + Arrays.toString(numsList[i]));
42 |
43 | quickSort(numsList[i]);
44 |
45 | System.out.println(" After Sorting");
46 | System.out.println(" " + Arrays.toString(numsList[i]));
47 | System.out.println("------------------------------------------------\n");
48 | }
49 | }
50 |
51 | /**
52 | * Method to perform quick sort using Hoare's partitioning scheme
53 | *
54 | * @param arr - int[]
55 | * @param low - int
56 | * @param high - int
57 | */
58 | static int partition(int[] arr, int low, int high) {
59 |
60 | // [55, 23, 26, 2, 25]
61 |
62 | // Initializing pivot's index to low
63 | int pivotValue = arr[low];
64 | int i = low;
65 | int j = high;
66 |
67 | // Loop until i pointer crosses j pointer
68 | while (i < j) {
69 |
70 | // Increment the 'i' pointer till it finds an element greater than pivot
71 | while (i <= high && arr[i] <= pivotValue) {
72 | i++;
73 | }
74 |
75 | // Decrement the 'j' pointer till it finds an element less than pivot
76 | while (arr[j] > pivotValue) {
77 | j--;
78 | }
79 |
80 | // Swap the numbers on i and j
81 | if (i < j) {
82 | // Swap arr[i] and arr[j]
83 | int temp = arr[i];
84 | arr[i] = arr[j];
85 | arr[j] = temp;
86 | }
87 | }
88 |
89 | // Swap pivot element with element on j pointer
90 | arr[low] = arr[j];
91 | arr[j] = pivotValue;
92 |
93 | return j; // return the pivot index
94 | }
95 |
96 | /**
97 | * Recursive function to implement QuickSort
98 | *
99 | * @param arr - int[]
100 | * @param low - int
101 | * @param high - int
102 | */
103 | static void quickSortRec(int[] arr, int low, int high) {
104 |
105 | if (high > low) {
106 |
107 | // Pivot index is the partitioning index
108 | int pivotIndex = partition(arr, low, high);
109 |
110 | // Sort elements before partition
111 | quickSortRec(arr, low, pivotIndex - 1);
112 |
113 | // Sort elements after partition
114 | quickSortRec(arr, pivotIndex + 1, high);
115 | }
116 | }
117 |
118 | /**
119 | * Method to perform quicksort
120 | *
121 | * @param arr - int[]
122 | */
123 | static void quickSort(int[] arr) {
124 | quickSortRec(arr, 0, arr.length - 1);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/hash_tables/PairWithTargetSum.java:
--------------------------------------------------------------------------------
1 | /**
2 | * PairWithTargetSum Class
3 | *
4 | *
5 | *
6 | * @question Problem Statement - Given an array of sorted numbers and a target sum, find a pair in
7 | * the array whose sum is equal to the given target.
8 | * Write a function to return the indices of the two numbers (i.e. the pair) such that they
9 | * add up to the given target.
10 | * @note Example 1:
11 | * Input: [1, 2, 3, 4, 6], target=6 Output: [1, 3] Explanation: The numbers at index 1 and 3
12 | * add up to 6: 2 + 4 = 6
13 | * @note Example 2:
14 | * Input: [2, 5, 9, 11], target=11 Output: [0, 2] Explanation: The numbers at index 0 and 2
15 | * add up to 11: 2 + 9 = 11
16 | * @note Solution - we can utilize a HashTable to search for the required pair. We can iterate
17 | * through the array one number at a time. Let’s say during our iteration we are at number ‘X’,
18 | * so we need to find ‘Y’ such that “X + Y == Target”. We will do two things here:
19 | * Search for ‘Y’ (which is equivalent to “Target - X Target−X ”) in the HashTable. If it is
20 | * there, we have found the required pair. Otherwise, insert “X” in the HashTable, so that we
21 | * can search it for the latter numbers.
22 | *
23 | * @note Time Complexity - The time complexity of the above algorithm will be O(N), where N is the
24 | * total number of elements in the given array.
25 | * @note Space Complexity - The algorithm runs in constant space O(1).
26 | * @author David Kariuki
27 | * @since 24/8/2022
28 | */
29 | package AceTheJavaCodingInterview.module2_data_structures.hash_tables;
30 |
31 | import java.util.HashMap;
32 |
33 | public class PairWithTargetSum {
34 |
35 | /**
36 | * Main method
37 | *
38 | * @param args - String[]
39 | */
40 | public static void main(String[] args) {
41 |
42 | int[] result = PairWithTargetSum.search(new int[] {1, 2, 3, 4, 6}, 6);
43 | System.out.println("Pair with target sum: [" + result[0] + ", " + result[1] + "]");
44 | result = PairWithTargetSum.search(new int[] {2, 5, 9, 11}, 11);
45 | System.out.println("Pair with target sum: [" + result[0] + ", " + result[1] + "]");
46 | }
47 |
48 | /**
49 | * Method to search array
50 | *
51 | * @param arr - int[]
52 | * @param targetSum -
53 | * @return int[]
54 | */
55 | public static int[] search(int[] arr, int targetSum) {
56 |
57 | // HashMap to store numbers and their indices
58 | HashMap
5 | *
6 | * @implNote Creating a tuple class as java does not support returning multiple arguments
7 | * @author David Kariuki
8 | * @since 22/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.tuples;
11 |
12 | public class Interval {
13 |
14 | public int first;
15 | public int second;
16 |
17 | /**
18 | * Class constructor
19 | *
20 | * @param x - X
21 | * @param y - Y
22 | */
23 | public Interval(int x, int y) {
24 | this.first = x;
25 | this.second = y;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/tuples/Tuple.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tuple Class
3 | *
4 | *
5 | *
6 | * @implNote Creating a tuple class as java does not support returning multiple arguments
7 | * @author David Kariuki
8 | * @since 18/8/2022
9 | */
10 | package AceTheJavaCodingInterview.module2_data_structures.tuples;
11 |
12 | public class Tuple> result = Permutations.findPermutations(new int[] {1, 3, 5});
64 | System.out.print("Here are all the permutations: " + result);
65 | }
66 |
67 | /**
68 | * Method to find permutation of an array
69 | *
70 | * @param nums - int[]
71 | * @return List
>
72 | */
73 | @SuppressWarnings("ConstantConditions")
74 | public static List
> findPermutations(int[] nums) {
75 |
76 | List
> result = new ArrayList<>();
77 | Queue
> permutations = new LinkedList<>();
78 | permutations.add(new ArrayList<>());
79 |
80 | for (int currentNumber : nums) {
81 |
82 | // Take all existing permutations and add the current number to create new
83 | // permutations
84 | int n = permutations.size();
85 |
86 | for (int i = 0; i < n; i++) {
87 | List
>
57 | */
58 | public static List
> findSubArrays(int[] arr, int target) {
59 |
60 | List
> result = new ArrayList<>();
61 |
62 | double product = 1;
63 | int left = 0;
64 |
65 | // Traverse array
66 | for (int right = 0; right < arr.length; right++) {
67 |
68 | product *= arr[right];
69 |
70 | while (product >= target && left < arr.length) {
71 | product /= arr[left++];
72 | }
73 |
74 | // Since the product of all numbers from left to right is less than the
75 | // target therefore, all sub-arrays from left to right will have a
76 | // product less than the target too; to avoid duplicates, we will start
77 | // with a sub-array containing only arr[right] and then extend it.
78 | List
> result = Subset.findSubsets(new int[] {1, 3});
46 | System.out.println("Here is the list of subsets: " + result);
47 |
48 | result = Subset.findSubsets(new int[] {1, 5, 3});
49 | System.out.println("Here is the list of subsets: " + result);
50 | }
51 |
52 | /**
53 | * Method to find subset
54 | *
55 | * @param nums - int[]
56 | * @return List
>
57 | */
58 | public static List
> findSubsets(int[] nums) {
59 |
60 | List
> subsets = new ArrayList<>();
61 |
62 | // Start by adding the empty subset
63 | subsets.add(new ArrayList<>());
64 |
65 | System.out.println("Adding empty to subset.");
66 |
67 | for (int currentNumber : nums) {
68 |
69 | System.out.println();
70 |
71 | // Take all existing subsets and insert the current number in them to
72 | // create new subsets
73 | int n = subsets.size();
74 |
75 | for (int i = 0; i < n; i++) {
76 |
77 | // Create a new subset from the existing subsets and insert the
78 | // current element to it
79 | List
> result = SubsetsWithDuplicates.findSubsets(new int[] {1, 3, 3});
62 | System.out.println("Here is the list of subsets: " + result);
63 |
64 | result = SubsetsWithDuplicates.findSubsets(new int[] {1, 5, 3, 3});
65 | System.out.println("Here is the list of subsets: " + result);
66 | }
67 |
68 | /**
69 | * Method to find subsets
70 | *
71 | * @param nums - int[]
72 | * @return List
>
73 | */
74 | @SuppressWarnings("UnusedAssignment")
75 | public static List
> findSubsets(int[] nums) {
76 |
77 | // Sort numbers to handle duplicates
78 | Arrays.sort(nums);
79 | List
> subsets = new ArrayList<>();
80 | subsets.add(new ArrayList<>());
81 |
82 | int startIndex = 0;
83 | int endIndex = 0;
84 |
85 | for (int i = 0; i < nums.length; i++) {
86 |
87 | startIndex = 0;
88 |
89 | // If the current and previous elements are the same, create new
90 | // subsets only from the subsets added in the previous step
91 | if (i > 0 && nums[i] == nums[i - 1]) {
92 | startIndex = endIndex + 1;
93 | }
94 |
95 | endIndex = subsets.size() - 1;
96 |
97 | for (int j = startIndex; j <= endIndex; j++) {
98 |
99 | // Create a new subset from the existing subset and add the current
100 | // element to it
101 | List
>
65 | */
66 | public static List
> searchTriplets(int[] arr) {
67 |
68 | Arrays.sort(arr); // Sort array
69 |
70 | List
> triplets = new ArrayList<>();
71 |
72 | // Traverse array
73 | for (int i = 0; i < arr.length - 2; i++) {
74 | if (i > 0 && arr[i] == arr[i - 1]) {
75 | continue; // Skip element to avoid duplicate triplets
76 | }
77 |
78 | searchPair(arr, -arr[i], i + 1, triplets); // Search pair
79 | }
80 |
81 | return triplets;
82 | }
83 |
84 | /**
85 | * Method to search for triplets
86 | *
87 | * @param arr - int[]
88 | * @param targetSum - int
89 | * @param left - int
90 | * @param triplets - List
>
91 | */
92 | public static void searchPair(int[] arr, int targetSum, int left, List
> triplets) {
93 |
94 | int right = arr.length - 1;
95 |
96 | while (left < right) {
97 |
98 | int currentSum = arr[left] + arr[right];
99 |
100 | if (currentSum == targetSum) {
101 |
102 | // Found the triplet
103 | triplets.add(Arrays.asList(-targetSum, arr[left], arr[right]));
104 | left++;
105 | right--;
106 |
107 | while (left < right && arr[left] == arr[left - 1]) {
108 | left++; // Skip same element to avoid duplicate triplets
109 | }
110 |
111 | while (left < right && arr[right] == arr[right + 1]) {
112 | right--; // Skip same element to avoid duplicate triplets
113 | }
114 | } else if (targetSum > currentSum) {
115 | left++; // Pair with a bigger sum
116 | } else {
117 | right--; // Pair with a smaller sum
118 | }
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/TripletsWithSmallerSum_ReturnCount.java:
--------------------------------------------------------------------------------
1 | /**
2 | * TripletsWithSmallerSum_ReturnCount Class
3 | *
4 | *
>
48 | */
49 | public static List
> searchTriplets(int[] arr, int target) {
50 |
51 | Arrays.sort(arr); // Sort array
52 |
53 | List
> triplets = new ArrayList<>();
54 |
55 | for (int i = 0; i < arr.length - 2; i++) {
56 | searchPair(arr, target - arr[i], i, triplets);
57 | }
58 |
59 | return triplets;
60 | }
61 |
62 | /**
63 | * Method to search for pairs
64 | *
65 | * @param arr - int[]
66 | * @param targetSum - int
67 | * @param first - int
68 | * @param triplets - List
>
69 | */
70 | public static void searchPair(int[] arr, int targetSum, int first, List
> triplets) {
71 |
72 | int left = first + 1;
73 | int right = arr.length - 1;
74 |
75 | while (left < right) {
76 |
77 | if (arr[left] + arr[right] < targetSum) {
78 | // Found the triplet. Since arr[right] >= arr[left], therefore, we can
79 | // replace arr[right] by any number between left and right to get a sum
80 | // less than the target sum
81 |
82 | for (int i = right; i > left; i--) {
83 | triplets.add(Arrays.asList(arr[first], arr[left], arr[i]));
84 | }
85 |
86 | left++;
87 |
88 | } else {
89 | right--; // Need a pair with a smaller sum
90 | }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/TripletsWithSmallerSum_ReturnList.java:
--------------------------------------------------------------------------------
1 | /**
2 | * TripletsWithSmallerSum_ReturnList Class
3 | *
4 | *
19 |
20 | ### Notes
21 |
22 | 1. If the size and the values of an array are known in advance, we can use the array literal for adding elements in an array.
23 | - datatype[] arrayName = {Comma Separated list of values};
24 | 2. In Java, arrays are dynamically allocated. Arrays are stored in the memory using a reference pointer, which points to the first element.
25 | 3. Pointers - References are used to explicitly store memory locations that hold a value or an object.
26 | 4. A Two Dimensional Array is an array of references that holds references to other arrays.
27 | 5. In 2D arrays, all values must have the same data type. This means that you can’t store an array of integers next to an array of strings and vice versa. For example, if one array is declared of type int, then its pointer can’t point to
28 | the string type array. Each element must be of the same data type.
29 |
--------------------------------------------------------------------------------
/app/src/main/java/AceTheJavaCodingInterview/module2_data_structures/arrays/binary_search/BinarySearchOnSortedArray_Iterative.java:
--------------------------------------------------------------------------------
1 | /**
2 | * BinarySearchOnSortedArray_Iterative Class
3 | *
4 | *