|
| 1 | +/* |
| 2 | +Problem Name : Minimum Number of Removals to Make Mountain Array |
| 3 | +1671. Minimum Number of Removals to Make Mountain Array |
| 4 | +Hard |
| 5 | +
|
| 6 | +You may recall that an array arr is a mountain array if and only if: |
| 7 | +arr.length >= 3 |
| 8 | +There exists some index i (0-indexed) with 0 < i < arr.length - 1 such that: |
| 9 | +arr[0] < arr[1] < ... < arr[i - 1] < arr[i] |
| 10 | +arr[i] > arr[i + 1] > ... > arr[arr.length - 1] |
| 11 | +Given an integer array nums, return the minimum number of elements to remove to make nums a mountain array. |
| 12 | +
|
| 13 | +Example 1: |
| 14 | +Input: nums = [1,3,1] |
| 15 | +Output: 0 |
| 16 | +Explanation: The array itself is a mountain array so we do not need to remove any elements. |
| 17 | +
|
| 18 | +Example 2: |
| 19 | +Input: nums = [2,1,1,5,6,2,3,1] |
| 20 | +Output: 3 |
| 21 | +Explanation: One solution is to remove the elements at indices 0, 1, and 5, making the array nums = [1,5,6,3,1]. |
| 22 | +
|
| 23 | +Constraints: |
| 24 | +
|
| 25 | +3 <= nums.length <= 1000 |
| 26 | +1 <= nums[i] <= 109 |
| 27 | +It is guaranteed that you can make a mountain array out of nums. |
| 28 | +*/ |
| 29 | + |
| 30 | +class Solution { |
| 31 | + public int minimumMountainRemovals(int[] nums) { |
| 32 | + // Explanation:: LIS :: |
| 33 | + //Since we need to find the no. of deletion to make mountain array:: |
| 34 | + // So if we apply LIS from front and back add the max valueandreduce -1: |
| 35 | + // Eg : [2,1,1,5,6,2,3,1] |
| 36 | + // front:1,1,1,2,3,2,3,1 |
| 37 | + // back :2,1,1,3,4,2,2,1 |
| 38 | + //------------------------ |
| 39 | + // 7-1 =6 |
| 40 | + //Note: Botonic array can't be montain arr: mountains must have dec & ase |
| 41 | + // part: |
| 42 | + |
| 43 | + // return total len-mountain : no. of deletion: |
| 44 | + |
| 45 | + |
| 46 | + //*IMP :: Point If we have Increasing party only or decreasing part only |
| 47 | + // not valid one:: |
| 48 | + // since when ever we have lis==1 && lds ==1 we can skip it.. |
| 49 | + |
| 50 | + // TC : O(n^2) |
| 51 | + // SC : O(n)+O(n) |
| 52 | + //return solveLIS(nums); |
| 53 | + |
| 54 | + //Lets think of optimise:: |
| 55 | + // TC : O(nlogn) |
| 56 | + //SC : O(n)+O(n) |
| 57 | + return solve(nums); |
| 58 | + |
| 59 | + |
| 60 | + |
| 61 | + |
| 62 | + } |
| 63 | + public static int solveLIS(int[] arr){ |
| 64 | + int n=arr.length; |
| 65 | + int flis[] =new int[n]; |
| 66 | + int blis[] =new int[n]; |
| 67 | + Arrays.fill(flis,1); |
| 68 | + Arrays.fill(blis,1); |
| 69 | + |
| 70 | + for(int i=1;i<n;i++){ |
| 71 | + for(int j=0;j<i;j++){ |
| 72 | + if(arr[i]>arr[j] && 1+flis[j]>flis[i]){ |
| 73 | + flis[i]=1+flis[j]; |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | + int maxi=0; |
| 78 | + for(int i=n-1;i>=0;i--){ |
| 79 | + for(int j=n-1;j>i;j--){ |
| 80 | + if(arr[i]>arr[j] && 1+blis[j]>blis[i]){ |
| 81 | + blis[i]=1+blis[j]; |
| 82 | + } |
| 83 | + } |
| 84 | + // imp: case it can't be just increasing or decresing:: |
| 85 | + //ex : 9 8 1 7 6 5 4 3 2 1 |
| 86 | + // lis:1 1 1 2 2 2 2 2 2 1 |
| 87 | + // lds:9 8 1 7 6 5 4 3 2 1 |
| 88 | + //-------------------------- |
| 89 | + //lets understand :: |
| 90 | + // 9 8 7 6 5 4 3 2 1 -- general : not valid since it decresing part |
| 91 | + // only :: mountain array must have both part :: |
| 92 | + if(flis[i]>1 && blis[i]>1){ |
| 93 | + maxi =Math.max(maxi,flis[i]+blis[i]-1); |
| 94 | + } |
| 95 | + |
| 96 | + } |
| 97 | + return n-maxi; |
| 98 | + } |
| 99 | + public static int solve(int[] nums){ |
| 100 | + int n =nums.length; |
| 101 | + int lis[] =new int[n]; |
| 102 | + int lds[] =new int[n]; |
| 103 | + |
| 104 | + |
| 105 | + ArrayList<Integer> temp =new ArrayList<>(); |
| 106 | + |
| 107 | + //LIS:: |
| 108 | + temp.add(nums[0]); |
| 109 | + for(int i=1;i<n;i++){ |
| 110 | + if(temp.get(temp.size()-1)<nums[i]){ |
| 111 | + temp.add(nums[i]); |
| 112 | + }else{ |
| 113 | + int pos = binarySearch(nums[i],temp); |
| 114 | + temp.set(pos,nums[i]); |
| 115 | + } |
| 116 | + lis[i] =temp.size(); |
| 117 | + } |
| 118 | + |
| 119 | + temp.clear(); |
| 120 | + //LDS:: |
| 121 | + temp.add(nums[n-1]); |
| 122 | + for(int i=n-2;i>=0;i--){ |
| 123 | + if(temp.get(temp.size()-1)<nums[i] ){ |
| 124 | + temp.add(nums[i]); |
| 125 | + }else{ |
| 126 | + int pos = binarySearch(nums[i],temp); |
| 127 | + temp.set(pos,nums[i]); |
| 128 | + } |
| 129 | + lds[i] =temp.size(); |
| 130 | + |
| 131 | + } |
| 132 | + int maxi=0; |
| 133 | + for(int i=0;i<n;i++){ |
| 134 | + // skip the completely incresing / decresing case::) |
| 135 | + if(lis[i]>1 && lds[i]>1){ |
| 136 | + maxi =Math.max(maxi,lis[i]+lds[i]-1); |
| 137 | + } |
| 138 | + } |
| 139 | + return nums.length-maxi; |
| 140 | + |
| 141 | + } |
| 142 | + public static int binarySearch(int target,ArrayList<Integer> arr){ |
| 143 | + int l=0; |
| 144 | + int h=arr.size()-1; |
| 145 | + |
| 146 | + while(l<=h){ |
| 147 | + int m =l+(h-l)/2; |
| 148 | + if(arr.get(m)==target){ |
| 149 | + return m; |
| 150 | + }else if(arr.get(m)>target){ |
| 151 | + h=m-1; |
| 152 | + }else{ |
| 153 | + l=m+1; |
| 154 | + } |
| 155 | + } |
| 156 | + return l; |
| 157 | + } |
| 158 | +} |
0 commit comments