diff --git a/delete-and-earn.java b/delete-and-earn.java new file mode 100644 index 00000000..db47b771 --- /dev/null +++ b/delete-and-earn.java @@ -0,0 +1,110 @@ +// Solution - 1 + +// TimeComplexity: O(n + maxValue) +// SpaceComplexity: O(maxValue) +// Explanation: First, I convert the problem into a House Robber pattern. +// I build an array arr where arr[i] stores the total points earned by taking number i (i.e., sum of all occurrences of i). +// Since picking i deletes i-1 and i+1, it becomes identical to the house robber problem. + +class Solution { + public int deleteAndEarn(int[] nums) { + + int max = Integer.MIN_VALUE; + for(int num: nums) { + if (num>max) max=num; + } + int[] arr = new int[max+1]; + for(int num:nums) { + arr[num]+=num; + } + int[] dp = new int[arr.length+1]; + dp[1] = arr[0]; + + for(int i=2; imax) max=num; + } + int[] arr = new int[max+1]; + Integer[] dp = new Integer[max+1]; + for(int num:nums) { + arr[num]+=num; + } + + return helper(arr, 0, dp); + + } + + private int helper(int[] arr, int idx, Integer[] dp) { + if(idx>=arr.length) return 0; + if(dp[idx] !=null) { + return dp[idx]; + } + + // No choose + int case1= arr[idx]+ helper(arr, idx+2, dp); + + // no choose + int case2= helper(arr, idx+1, dp); + int max = Math.max(case1, case2); + dp[idx] =max; + + return max; + + } +} + +// Solution - 3 + +// TimeComplexity: Exponential +// SpaceComplexity: O(maxValue) +// Explanation: Here I recursively try both choices (take or skip) without memoization. +// This causes repeated evaluation of the same states, leading to exponential time complexity. + + +class Solution { + public int deleteAndEarn(int[] nums) { + int max = Integer.MIN_VALUE; + for(int num: nums) { + if (num>max) max=num; + } + int[] arr = new int[max+1]; + for(int num:nums) { + arr[num]+=num; + } + + return helper(arr, 0); + + } + + private int helper(int[] arr, int idx) { + if(idx>=arr.length) return 0; + + // No choose + int case1= arr[idx]+ helper(arr, idx+2); + + // no choose + int case2= helper(arr, idx+1); + + return Math.max(case1, case2); + + } +} \ No newline at end of file diff --git a/minimum-falling-path-sum.java b/minimum-falling-path-sum.java new file mode 100644 index 00000000..53cc1c0a --- /dev/null +++ b/minimum-falling-path-sum.java @@ -0,0 +1,135 @@ + +// Solution - 1 + +// TimeComplexity: O(n²) +// SpaceComplexity: O(n) +// Explanation: I solve it from the bottom row upward. I keep a prev array that stores the minimum path sums from the row below. +// For each cell, I add its value to the minimum of the three possible downward moves (down, down-left, down-right). After processing a row, I move upward. +// Finally, I return the minimum value in the top row. +class Solution { + public int minFallingPathSum(int[][] matrix) { + int n = matrix.length; + int[] prev = matrix[n-1].clone(); + + for(int i=n-2; i>=0; i--){ + int[] curr = new int[n]; + for (int j = 0; j < n; j++) { + int down = prev[j]; + int left = (j > 0) ? prev[j - 1] : Integer.MAX_VALUE; + int right = (j < n - 1) ? prev[j + 1] : Integer.MAX_VALUE; + + curr[j] = matrix[i][j] + Math.min(down, Math.min(left, right)); + } + + prev = curr; // move upward + } + int min = Integer.MAX_VALUE; + + for (int val : prev) { + min = Math.min(min, val); + } + return min; + + } +} + + +// Solution - 2 + +// TimeComplexity: O(n²) +// SpaceComplexity: O(1) +// Explanation: Here I modify the matrix directly. Starting from the second-last row, +// I update each cell by adding the minimum of the three possible cells from the row below. +// At the end, the first row contains the minimum falling path sums, and I return the minimum among them. + +class Solution { + public int minFallingPathSum(int[][] matrix) { + int m = matrix.length; + for(int i=m-2; i>=0; i--){ + for(int j=0; j 0) + ? matrix[i+1][j-1] + : Integer.MAX_VALUE; + + int right = (j < m-1) + ? matrix[i+1][j+1] + : Integer.MAX_VALUE; + + matrix[i][j] += Math.min(down, Math.min(left, right)); + } + } + int min = Integer.MAX_VALUE; + + for(int i=0; i=m || c>=m) return Integer.MAX_VALUE - 10000; + if(r==m-1) return mat[r][c]; + if(dp[r][c] !=null) return dp[r][c]; + + int case1= mat[r][c] + helper(mat, r+1, c-1, m, dp); + int case2= mat[r][c] + helper(mat, r+1, c, m, dp); + int case3= mat[r][c] + helper(mat, r+1, c+1, m, dp); + int min = Math.min(case1, Math.min(case2,case3)); + dp[r][c] = min; + return min; + } +} + + +// Solution - 4 + +// TimeComplexity: O(3^n) +// SpaceComplexity: O(n) +// Explanation: Here I recursively explore all possible downward paths without memoization. +// This leads to repeated recomputation of the same subproblems and exponential time complexity. + +class Solution { + public int minFallingPathSum(int[][] matrix) { + int m = matrix.length; + int min = Integer.MAX_VALUE; + for(int i=0; i=m || c>=m) return 101; + if(r==m-1) return mat[r][c]; + + int case1= mat[r][c] + helper(mat, r+1, c-1, m); + int case2= mat[r][c] + helper(mat, r+1, c, m); + int case3= mat[r][c] + helper(mat, r+1, c+1, m); + return Math.min(case1, Math.min(case2,case3)); + } +}