├── BinarySearch.java ├── BinarySearchIterative.java ├── BinarySearchString.java ├── CountingSort.java ├── FloydCycleDetectionAlgorithm.java ├── HeapSort.java ├── InsertionSort.java ├── KadaneAlgorithm.java ├── MergeSort.java ├── QuickSelect.java ├── QuickSort.java ├── README.md ├── SelectionSort.java ├── SequentialNonRepeating.java ├── SinglyLinkedListReversal.java ├── SlidingWindow.java └── TopologicalSort.java /BinarySearch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Binary Search is a widely used searching algorithm that efficiently finds the position of a target value 3 | * within a sorted array. 4 | * It works by repeatedly dividing the search interval in half. 5 | */ 6 | public class BinarySearch { 7 | 8 | public static int binarySearchRecursive(int[] arr, int target, int left, int right) { 9 | 10 | if(left > right){ 11 | return -1; 12 | } 13 | 14 | int mid = (left + right) / 2; 15 | 16 | if(arr[mid] == target) { 17 | return mid; 18 | } 19 | else if (target < arr[mid]) { 20 | return binarySearchRecursive(arr, target, left, mid -1); 21 | } 22 | else { 23 | return binarySearchRecursive(arr, target, mid+1, right); 24 | } 25 | 26 | } 27 | 28 | public static void main(String[] args) { 29 | int[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; 30 | int target = 11; 31 | 32 | int result = binarySearchRecursive(arr, target, 0, arr.length-1); 33 | if(result != -1) { 34 | System.out.println("Target found at index: " + result); 35 | }else{ 36 | System.out.println("Target not found"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /BinarySearchIterative.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Binary Search is a widely used searching algorithm that efficiently finds the position of a target value 3 | * within a sorted array. 4 | * It works by repeatedly dividing the search interval in half. 5 | */ 6 | public class BinarySearchIterative { 7 | public static int binarySearchIterative(int[] arr, int target) { 8 | int left = 0; 9 | int right = arr.length - 1; 10 | 11 | while (left <= right){ 12 | int mid = left + (right - left) / 2; 13 | 14 | if(arr[mid] == target) { 15 | return mid; 16 | } 17 | else if (target < arr[mid]) { 18 | right = mid - 1; 19 | } 20 | else{ 21 | left = mid + 1; 22 | } 23 | } 24 | 25 | return -1; 26 | } 27 | 28 | public static void main(String[] args) { 29 | int[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; 30 | int target = 11; 31 | 32 | int result = binarySearchIterative(arr, target); 33 | 34 | if(result != -1) { 35 | System.out.println("Target found at index: " + result); 36 | } 37 | else { 38 | System.out.println("Target not found"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /BinarySearchString.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Binary Search is a widely used searching algorithm that efficiently finds the position of a target value 3 | * within a sorted array. 4 | * It works by repeatedly dividing the search interval in half. 5 | */ 6 | public class BinarySearchString { 7 | public static int binarySearchRecursive(String[] arr, String target, int left, int right) { 8 | 9 | if(left > right){ 10 | return -1; 11 | } 12 | 13 | int mid = left + (right - left) / 2; 14 | 15 | int compareResult = target.compareTo(arr[mid]); 16 | 17 | if(compareResult == 0) { 18 | return mid; 19 | }else if(compareResult < 0) { 20 | return binarySearchRecursive(arr, target, left, mid -1); 21 | }else { 22 | return binarySearchRecursive(arr, target, mid+1, right); 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | String[] arr = {"apple", "banana", "cherry", "date", "elderberry", "fig"}; 28 | String target = "cherry"; 29 | 30 | int result = binarySearchRecursive(arr, target, 0, arr.length-1); 31 | if(result != -1) { 32 | System.out.println("Target found at index: " + result); 33 | }else{ 34 | System.out.println("Target not found"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /CountingSort.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | /** 4 | * Counting Sort is an efficient sorting algorithm that operates in linear time complexity O(n+k), 5 | * where n is the number of elements in the input array and k is the range of the input (maximum element - minimum element + 1). 6 | * Counting Sort is particularly useful when the range of input values is not significantly greater than the number of elements in the array. 7 | * The basic idea behind Counting Sort is to count the occurrences of each unique element in the input array and then use this information 8 | * to place each element in its correct sorted position. 9 | */ 10 | public class CountingSort { 11 | 12 | public static void countingSort(int[] array) { 13 | if(array == null || array.length == 0) { 14 | return; 15 | } 16 | 17 | int max = Arrays.stream(array).max().getAsInt(); 18 | int[] countArray = new int[max + 1]; 19 | 20 | for(int num : array) { 21 | countArray[num]++; 22 | } 23 | 24 | for(int i = 1; i < countArray.length; i++) { 25 | countArray[i] += countArray[i-1]; 26 | } 27 | 28 | int[] tempArray = new int[array.length]; 29 | for(int i = array.length - 1; i>= 0; i--) { 30 | tempArray[countArray[array[i]] - 1] = array[i]; 31 | countArray[array[i]]--; 32 | } 33 | 34 | System.arraycopy(tempArray, 0, array, 0, array.length); 35 | } 36 | 37 | public static void main(String[] args) { 38 | int[] arr = {4,2,2,8,3,3,1}; 39 | countingSort(arr); 40 | 41 | System.out.println(Arrays.toString(arr)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /FloydCycleDetectionAlgorithm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Floyd's Cycle Detection Algorithm, also known as the "tortoise and hare" algorithm, 3 | * is a popular algorithm used to detect cycles in a linked list or any cyclic sequence. 4 | * It's particularly efficient in terms of both time and space complexity. 5 | */ 6 | class ListNode { 7 | int val; 8 | ListNode next; 9 | 10 | ListNode(int x) { 11 | this.val = x; 12 | this.next = null; 13 | } 14 | } 15 | 16 | public class FloydCycleDetectionAlgorithm { 17 | 18 | public boolean hasCycle(ListNode head) { 19 | if(head == null || head.next == null) { 20 | return false; 21 | } 22 | 23 | ListNode slow = head; 24 | ListNode fast = head; 25 | 26 | while(fast != null && fast.next != null) { 27 | slow = slow.next; 28 | fast = fast.next.next; 29 | 30 | if(slow == fast) { 31 | return true; 32 | } 33 | } 34 | 35 | return false; 36 | } 37 | 38 | public static void main(String[] args) { 39 | 40 | FloydCycleDetectionAlgorithm floydCycleDetectionAlgorithm = new FloydCycleDetectionAlgorithm(); 41 | 42 | ListNode head = new ListNode(1); 43 | head.next = new ListNode(2); 44 | head.next.next = new ListNode(3); 45 | head.next.next.next = new ListNode(4); 46 | head.next.next.next.next = new ListNode(5); 47 | head.next.next.next.next.next = head.next.next; // Cycle 48 | 49 | boolean hasCycle = floydCycleDetectionAlgorithm.hasCycle(head); 50 | System.out.println("Does the linked list have a cycle? " + hasCycle); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /HeapSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Heap Sort 3 | * a comparison-based sorting algorithm that uses a binary heap data structure to sort elements. 4 | * It works by first building a heap from the input array and then repeatedly extracting the maximum (for ascending order) 5 | * or minimum (for descending order) element from the heap and placing it at the end of the array. 6 | */ 7 | public class HeapSort { 8 | 9 | public static void heapSort(int[] arr) { 10 | int n = arr.length; 11 | 12 | for(int i = n/2 -1; i >= 0; i--) { 13 | heapify(arr, n, i); 14 | } 15 | 16 | for(int i = n-1; i > 0; i--) { 17 | int temp = arr[0]; 18 | arr[0] = arr[i]; 19 | arr[i] = temp; 20 | 21 | heapify(arr, i, 0); 22 | } 23 | } 24 | 25 | public static void heapify(int[] arr, int n, int i) { 26 | int largest = i; 27 | int left = 2*i + 1; 28 | int right = 2*i + 2; 29 | 30 | // Change the comparison to change the sorting order 31 | if(left < n && arr[left] > arr[largest]) 32 | largest = left; 33 | 34 | // Change the comparison to change the sorting order 35 | if(right < n && arr[right] > arr[largest]) 36 | largest = right; 37 | 38 | if(largest != i) { 39 | int swap = arr[i]; 40 | arr[i] = arr[largest]; 41 | arr[largest] = swap; 42 | 43 | heapify(arr, n, largest); 44 | } 45 | } 46 | 47 | public static void printArray(int[] arr) { 48 | for(int i : arr) { 49 | System.out.print(i + " "); 50 | } 51 | System.out.println(); 52 | } 53 | 54 | public static void main(String[] args) { 55 | int[] arr = {12, 11, 13, 5, 6, 7, 17, 22}; 56 | heapSort(arr); 57 | printArray(arr); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /InsertionSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Insertion Sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. 3 | * It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. 4 | * However, it is efficient for small lists or nearly sorted lists. 5 | */ 6 | public class InsertionSort { 7 | public static void InsertionSort(int[] array) { 8 | int n = array.length; 9 | 10 | for(int i = 1; i < n; i++) { 11 | int key = array[i]; 12 | int j = i - 1; 13 | 14 | while(j >= 0 && array[j] > key) { 15 | array[j+1] = array[j]; 16 | j = j - 1; 17 | } 18 | 19 | array[j + 1] = key; 20 | } 21 | } 22 | 23 | public static void main(String[] args) { 24 | int[] arr = {3,2,1,5,4}; 25 | InsertionSort(arr); 26 | 27 | System.out.println("Sorted array:"); 28 | printArray(arr); 29 | } 30 | 31 | public static void printArray(int[] arr) { 32 | for(int i = 0; i < arr.length; i++) { 33 | System.out.print(arr[i] + " "); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /KadaneAlgorithm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Kadane's Algorithm is an efficient algorithm used to find the maximum subarray sum within a given array of integers. 3 | * It is particularly useful for solving problems related to maximum subarray sum in linear time complexity. 4 | */ 5 | public class KadaneAlgorithm { 6 | public static int kadane(int[] arr) { 7 | int maxCurrent = arr[0]; 8 | int maxGlobal = arr[0]; 9 | 10 | for(int i = 1; i < arr.length; i++) { 11 | maxCurrent = Math.max(arr[i], maxCurrent + arr[i]); 12 | maxGlobal = Math.max(maxGlobal, maxCurrent); 13 | } 14 | 15 | return maxGlobal; 16 | } 17 | 18 | public static void main(String[] args) { 19 | int[] arr = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; 20 | System.out.println("Maximum sum subarray: " + kadane(arr)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MergeSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The merge sort is a sorting algorithm that uses a divide-and-conquer strategy to sort an array of elements. 3 | * It is an efficient sorting algorithm, with an average time complexity of O(n log n). 4 | * The merge sort algorithm works by recursively dividing the input array into two halves until each half contains only one element or is empty. 5 | * Then, it merges the sorted subarrays back together to produce the final sorted array. 6 | */ 7 | 8 | public class MergeSort { 9 | 10 | public static void main(String[] args) { 11 | int[] arr = {3, 9, 10, 1, 8, 7, 5, 2}; 12 | mergeSort(arr); 13 | 14 | for(int i: arr) { 15 | System.out.print(i + " "); 16 | } 17 | 18 | } 19 | 20 | public static void mergeSort(int[] array) { 21 | if(array == null || array.length <= 1) { 22 | return; 23 | } 24 | 25 | int mid = array.length / 2; 26 | int[] leftArray = new int[mid]; 27 | int[] rightArray = new int[array.length - mid]; 28 | 29 | System.arraycopy(array, 0, leftArray, 0, mid); 30 | 31 | if(array.length - mid >= 0) { 32 | System.arraycopy(array, mid, rightArray, 0, array.length - mid); 33 | } 34 | 35 | mergeSort(leftArray); 36 | mergeSort(rightArray); 37 | merge(leftArray, rightArray, array); 38 | } 39 | 40 | private static void merge(int[] leftArray, int[] rightArray, int[] array) { 41 | int i = 0, j = 0, k = 0; 42 | 43 | while(i < leftArray.length && j < rightArray.length) { 44 | if(leftArray[i] < rightArray[j]) { 45 | array[k++] = leftArray[i++]; 46 | } 47 | else { 48 | array[k++] = rightArray[j++]; 49 | } 50 | } 51 | 52 | while(i < leftArray.length) { 53 | array[k++] = leftArray[i++]; 54 | } 55 | 56 | while(j < rightArray.length) { 57 | array[k++] = rightArray[j++]; 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /QuickSelect.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | /* 3 | * Quick Select is an algorithm used to find the k-th smallest (or largest) element in an unordered list or array. 4 | * It's an efficient algorithm with an average time complexity of O(n), where n is the number of elements in the array. 5 | */ 6 | public class QuickSelect { 7 | 8 | public static int quickSelect(int[] arr, int k) { 9 | return quickSelect(arr, 0, arr.length -1, k - 1); 10 | } 11 | 12 | private static int quickSelect(int[] arr, int left, int right, int k) { 13 | if(left == right) { 14 | return arr[left]; 15 | } 16 | 17 | Random random = new Random(); 18 | int pivotIndex = left + random.nextInt(right - left + 1); 19 | pivotIndex = partition(arr, left, right, pivotIndex); 20 | 21 | if(k == pivotIndex) { 22 | return arr[k]; 23 | } else if( k < pivotIndex ) { 24 | return quickSelect(arr, left, pivotIndex - 1, k); 25 | } else { 26 | return quickSelect(arr, pivotIndex + 1, right, k); 27 | } 28 | } 29 | 30 | private static int partition(int[] arr, int left, int right, int pivotIndex) { 31 | 32 | int pivotValue = arr[pivotIndex]; 33 | swap(arr, pivotIndex, right); 34 | 35 | int storeIndex = left; 36 | 37 | for(int i = left; i < right; i++) { 38 | if(arr[i] < pivotValue) { 39 | swap(arr, i, storeIndex); 40 | storeIndex++; 41 | } 42 | } 43 | swap(arr, storeIndex, right); 44 | return storeIndex; 45 | } 46 | 47 | private static void swap(int[] arr, int i, int j) { 48 | int temp = arr[i]; 49 | arr[i] = arr[j]; 50 | arr[j] = temp; 51 | } 52 | 53 | public static void main(String[] args) { 54 | int[] arr = {3,2,1,5,4}; 55 | int k = 3; 56 | int result = quickSelect(arr, k); 57 | 58 | //int n = arr.length; 59 | //int kthLargest = quickSelect(arr, n - k + 1); // Adjust k 60 | 61 | System.out.println(k +"th smallest element: " + result); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /QuickSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * QuickSort has an average time complexity of O(n log n) and is widely used due to its efficiency to o sort an array or list efficiently. 3 | */ 4 | public class QuickSort { 5 | 6 | public static void quickSort(int[] arr, int low, int high) { 7 | if(low < high) { 8 | int pIndex = partition(arr, low, high); 9 | quickSort(arr, low, pIndex-1); 10 | quickSort(arr, pIndex + 1, high); 11 | } 12 | } 13 | 14 | public static int partition(int[] arr, int low, int high) { 15 | int pivot = arr[high]; 16 | int i = low -1; 17 | 18 | for(int j = low; j < high; j++) { 19 | if(arr[j] <= pivot) { 20 | i++; 21 | int temp = arr[i]; 22 | arr[i] = arr[j]; 23 | arr[j] = temp; 24 | } 25 | } 26 | 27 | int temp = arr[i+1]; 28 | arr[i+1] = arr[high]; 29 | arr[high] = temp; 30 | 31 | return i+1; 32 | } 33 | 34 | public static void printArray(int[] arr) { 35 | for(int i = 0; i < arr.length; i++) { 36 | System.out.print(arr[i] + " "); 37 | } 38 | System.out.println(); 39 | } 40 | 41 | public static void main(String[] args) { 42 | int[] arr = {5, 2, 4, 6, 1, 3}; 43 | quickSort(arr, 0, arr.length-1); 44 | printArray(arr); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AlgorithmsStudies 2 | My Own solution to some common algorithms, for studying purposes. 3 | 4 | * Based on the algorithm studies list proposed by @araujo88 at the [important-algorithms](https://github.com/araujo88/important-algorithms) 5 | -------------------------------------------------------------------------------- /SelectionSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Selection Sort is a simple sorting algorithm that repeatedly selects the minimum element 3 | * from an unsorted portion of the array and moves it to the beginning. 4 | * The Selection Sort algorithm has a time complexity of O(n^2), where 'n' is the number of elements in the array. 5 | * Although it is not the most efficient sorting algorithm, it can be useful for small data sets or when simplicity is preferred over performance. 6 | * For larger datasets, more efficient sorting algorithms such as Merge Sort, Quick Sort, or Heap Sort are preferred due to their better time complexities. 7 | */ 8 | public class SelectionSort { 9 | 10 | public static void selectionSort(int[] arr) { 11 | int n = arr.length; 12 | 13 | for(int i = 0; i < n-1; i++) { 14 | int minindex = i; 15 | 16 | for(int j = i+1; j < n; j++) { 17 | if(arr[j] < arr[minindex]) { 18 | minindex = j; 19 | } 20 | } 21 | 22 | int temp = arr[minindex]; 23 | arr[minindex] = arr[i]; 24 | arr[i] = temp; 25 | } 26 | } 27 | 28 | public static void main (String[] args) { 29 | int[] arr = {64, 25, 12, 22, 11}; 30 | selectionSort(arr); 31 | 32 | for(int i: arr) { 33 | System.out.print(i + " "); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SequentialNonRepeating.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.Set; 3 | 4 | public class SequentialNonRepeating { 5 | 6 | public static void main(String[] args) { 7 | int output = charSequence("abcc", 2); 8 | 9 | System.out.println(output); 10 | } 11 | 12 | public static int charSequence(String str, int K) { 13 | int n = str.length(); 14 | int count = 0; 15 | 16 | if (K>n) { 17 | return 0; 18 | } 19 | 20 | for (int i = 0; i <= n - K; i++){ 21 | String substring = str.substring(i, i+K); 22 | if(hasAllUniqueCharacters(substring)) { 23 | count++; 24 | } 25 | } 26 | 27 | return count; 28 | } 29 | 30 | public static boolean hasAllUniqueCharacters(String s) { 31 | Set set = new HashSet<>(); 32 | for(char ch : s.toCharArray()) { 33 | if(!set.add(ch)) { 34 | return false; 35 | } 36 | } 37 | 38 | return true; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SinglyLinkedListReversal.java: -------------------------------------------------------------------------------- 1 | /* Reversing a singly linked list involves changing the direction of the pointers in each node so that the last node becomes the first node, 2 | * the second-to-last node becomes the second node, and so on, until the first node becomes the last node. 3 | */ 4 | class ListNode { 5 | int val; 6 | ListNode next; 7 | ListNode(int x) { val = x; } 8 | } 9 | 10 | public class SinglyLinkedListReversal { 11 | public ListNode reverseList(ListNode head) { 12 | ListNode previous = null; 13 | ListNode current = head; 14 | ListNode next = null; 15 | 16 | while (current != null) { 17 | next = current.next; 18 | current.next = previous; 19 | previous = current; 20 | current = next; 21 | } 22 | 23 | head = previous; 24 | return head; 25 | } 26 | 27 | public void printList(ListNode head) { 28 | ListNode current = head; 29 | while(current != null) { 30 | System.out.print(current.val + " "); 31 | current = current.next; 32 | } 33 | System.out.println(); 34 | } 35 | 36 | public static void main(String[] args) { 37 | SinglyLinkedListReversal reversal = new SinglyLinkedListReversal(); 38 | 39 | ListNode head = new ListNode(1); 40 | head.next = new ListNode(2); 41 | head.next.next = new ListNode(3); 42 | head.next.next.next = new ListNode(4); 43 | head.next.next.next.next = new ListNode(5); 44 | 45 | System.out.println("Original list: "); 46 | reversal.printList(head); 47 | 48 | // Reversal 49 | head = reversal.reverseList(head); 50 | System.out.println("Reversed list: "); 51 | reversal.printList(head); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SlidingWindow.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Deque; 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /*The sliding window technique is a commonly used algorithmic approach for solving problems involving arrays or strings 7 | * where you need to find a subset (window) of elements that satisfies certain conditions. 8 | */ 9 | public class SlidingWindow { 10 | 11 | public static List findSubArray(int[] nums, int k) { 12 | List result = new ArrayList<>(); 13 | if(nums == null || nums.length == 0 || k <= 0) { 14 | return result; 15 | } 16 | 17 | Deque deque = new LinkedList<>(); 18 | for(int i = 0; i < nums.length; i++) { 19 | while(!deque.isEmpty() && deque.peek() < i -k +1) { 20 | deque.poll(); 21 | } 22 | 23 | while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]){ 24 | deque.pollLast(); 25 | } 26 | 27 | deque.offer(i); 28 | 29 | if(i >= k -1) { 30 | result.add(nums[deque.peek()]); 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | public static void main(String[] args) { 37 | int[] nums = {1,3,-1,-3,5,3,6,7}; 38 | int k = 3; 39 | List result = findSubArray(nums, k); 40 | 41 | System.out.println("Maximum elements in each sliding window of size " + k +" : " + result); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /TopologicalSort.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashMap; 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Queue; 7 | 8 | public class TopologicalSort { 9 | 10 | public static List topologicalSort(int numCourses, int[][] prerequisites) { 11 | Map> graph = new HashMap<>(); 12 | int[] inDegree = new int[numCourses]; 13 | 14 | for(int[] edge : prerequisites) { 15 | int from = edge[1]; 16 | int to = edge[0]; 17 | graph.computeIfAbsent(from, k -> new ArrayList<>()).add(to); 18 | inDegree[to]++; 19 | } 20 | 21 | Queue zeroInDegreeQueue = new LinkedList<>(); 22 | for(int i = 0; i < numCourses; i++) { 23 | if(inDegree[i] == 0) { 24 | zeroInDegreeQueue.offer(i); 25 | } 26 | } 27 | 28 | List topologicalOrder = new ArrayList<>(); 29 | while(!zeroInDegreeQueue.isEmpty()) { 30 | int u = zeroInDegreeQueue.poll(); 31 | topologicalOrder.add(u); 32 | 33 | if(graph.containsKey(u)) { 34 | for(int v : graph.get(u)) { 35 | inDegree[v]--; 36 | if(inDegree[v] == 0) { 37 | zeroInDegreeQueue.offer(v); 38 | } 39 | } 40 | } 41 | } 42 | 43 | if(topologicalOrder.size() != numCourses) { 44 | return new ArrayList<>(); 45 | } 46 | 47 | return topologicalOrder; 48 | } 49 | 50 | public static void main(String[] args) { 51 | int numCourses = 4; 52 | int[][] prerequisites = {{1,0}, {2,0}, {3,1}, {3,2}}; 53 | List result = topologicalSort(numCourses, prerequisites); 54 | System.out.println("Topological order: " + result); 55 | } 56 | } 57 | --------------------------------------------------------------------------------