diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..8280013 Binary files /dev/null and b/.DS_Store differ diff --git a/AP1403 - Algorithms/src/main/java/Exercises.java b/AP1403 - Algorithms/src/main/java/Exercises.java index 15a2133..de31de2 100644 --- a/AP1403 - Algorithms/src/main/java/Exercises.java +++ b/AP1403 - Algorithms/src/main/java/Exercises.java @@ -1,64 +1,98 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class Exercises { - /* - there is an array of positive integers as input of function and another integer for the target value - all the algorithm should do is to find those two integers in array which their multiplication is the target - then it should return an array of their indices - e.g. {1, 2, 3, 4} with target of 8 -> {1, 3} - - note: you should return the indices in ascending order and every array's solution is unique - */ public int[] productIndices(int[] values, int target) { - // todo + for (int i = 0; i < values.length; i++) { + for (int j = i + 1; j < values.length; j++) { + if (values[i] * values[j] == target) { + return new int[]{i,j}; + } + } + } return null; } - /* - given a matrix of random integers, you should do spiral traversal in it - e.g. if the matrix is as shown below: - 1 2 3 - 4 5 6 - 7 8 9 - then the spiral traversal of that is: - {1, 2, 3, 6, 9, 8, 7, 4, 5} - - so you should walk in that matrix in a curl and then add the numbers in order you've seen them in a 1D array - */ - public int[] spiralTraversal(int[][] values, int rows, int cols) { - // todo - return null; + public int[] spiralTraversal(int[][] values, int rows, int cols) { + int[] result = new int[rows * cols]; + int index = 0; + int top = 0, bottom = rows - 1, left = 0, right = cols - 1; + + while (top <= bottom && left <= right) { + for (int i = left; i <= right; i++){ + result[index++] = values[top][i]; + } + top++; + + if (top <= bottom) { + for (int i = top; i <= bottom; i++) { + result[index++] = values[i][right]; + } + right--; + } + + if (top <= bottom) { + for (int i = right; i >= left; i--) { + result[index++] = values[bottom][i]; + } + bottom--; + } + + if (left <= right) { + for (int i = bottom; i >= top; i--){ + result[index++] = values[i][left]; + } + left++; + } + } + return result; } - /* - integer partitioning is a combinatorics problem in discreet maths - the problem is to generate sum numbers which their summation is the input number + public static int[][] intPartitions(int n) { + List parts = new ArrayList<>(); + int[] partition = new int[n]; + int index = 0; - e.g. 1 -> all partitions of integer 3 are: - 3 - 2, 1 - 1, 1, 1 + partition[index] = n; - e.g. 2 -> for number 4 goes as: - 4 - 3, 1 - 2, 2 - 2, 1, 1 - 1, 1, 1, 1 + while (true) { + int[] validParts = Arrays.copyOf(partition, index + 1); + parts.add(validParts); - note: as you can see in examples, we want to generate distinct summations, which means 1, 2 and 2, 1 are no different - you should generate all partitions of the input number and + int remaining = 0; + while (index >= 0 && partition[index] == 1) { + remaining += partition[index]; + index--; + } - hint: you can measure the size and order of arrays by finding the pattern of partitions and their number - trust me, that one's fun and easy :) + if (index < 0) { + break; + } - if you're familiar with lists and arraylists, you can also edit method's body to use them instead of array - */ - public int[][] intPartitions(int n) { - // todo - return null; + partition[index]--; + remaining++; + + while (remaining > partition[index]) { + partition[index + 1] = partition[index]; + remaining -= partition[index]; + index++; + } + + partition[index + 1] = remaining; + index++; + } + + int[][] result = new int[parts.size()][]; + for (int i = 0; i < parts.size(); i++) { + result[i] = parts.get(i); + } + + return result; } public static void main(String[] args) { // you can test your code here } } +