|
| 1 | +<h1 align='center'>Kth - Largest - Sum - Contiguous - Subarray</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Kth Largest Sum Contiguous Subarray](https://www.geeksforgeeks.org/problems/k-th-largest-sum-contiguous-subarray/1) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +## Problem Explanation |
| 10 | +Given an array of integers, you are tasked to find the `k`-th largest sum among all possible contiguous subarrays of the array. |
| 11 | + |
| 12 | +#### Explanation with Example |
| 13 | +A contiguous subarray is a subarray that consists of consecutive elements from the original array. For example, if the array is `[1, 2, 3]`, the contiguous subarrays are: |
| 14 | +- `[1]` |
| 15 | +- `[2]` |
| 16 | +- `[3]` |
| 17 | +- `[1, 2]` |
| 18 | +- `[2, 3]` |
| 19 | +- `[1, 2, 3]` |
| 20 | + |
| 21 | +For each subarray, we calculate the sum: |
| 22 | +- `[1]` → sum is `1` |
| 23 | +- `[2]` → sum is `2` |
| 24 | +- `[3]` → sum is `3` |
| 25 | +- `[1, 2]` → sum is `3` |
| 26 | +- `[2, 3]` → sum is `5` |
| 27 | +- `[1, 2, 3]` → sum is `6` |
| 28 | + |
| 29 | +If `k = 2`, we need to find the 2nd largest sum. After sorting all sums `{1, 2, 3, 3, 5, 6}`, the 2nd largest is `5`. |
| 30 | + |
| 31 | +#### Approach to Solve the Problem |
| 32 | +1. **Identify All Contiguous Subarrays**: To find the `k`-th largest sum among all possible contiguous subarrays, we need to consider all of them. |
| 33 | +2. **Use a Min-Heap**: A min-heap (or priority queue) is ideal for tracking the largest `k` sums: |
| 34 | + - If the heap has less than `k` elements, push the sum directly. |
| 35 | + - Once the heap has `k` elements, compare the current sum with the smallest element in the heap (i.e., `pq.top()`). If the current sum is larger, replace `pq.top()` with the current sum to maintain only the largest `k` sums. |
| 36 | +3. **Result**: After processing all possible subarray sums, `pq.top()` will hold the `k`-th largest sum. |
| 37 | + |
| 38 | +## Problem Solution |
| 39 | +```cpp |
| 40 | +class Solution { |
| 41 | + public: |
| 42 | + int kthLargest(vector<int> &arr, int k) { |
| 43 | + priority_queue<int, vector<int>, greater<int>> pq; |
| 44 | + |
| 45 | + int n = arr.size(); |
| 46 | + |
| 47 | + for(int i = 0; i < n; i++){ |
| 48 | + |
| 49 | + int sum = 0; |
| 50 | + |
| 51 | + for(int j = i; j < n; j++){ |
| 52 | + sum += arr[j]; |
| 53 | + |
| 54 | + if(pq.size() < k){ |
| 55 | + pq.push(sum); |
| 56 | + }else{ |
| 57 | + if(sum > pq.top()){ |
| 58 | + pq.pop(); |
| 59 | + pq.push(sum); |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + return pq.top(); |
| 66 | + } |
| 67 | +}; |
| 68 | +``` |
| 69 | +
|
| 70 | +## Problem Solution Explanation |
| 71 | +
|
| 72 | +```cpp |
| 73 | +class Solution { |
| 74 | + public: |
| 75 | + int kthLargest(vector<int> &arr, int k) { |
| 76 | +``` |
| 77 | + |
| 78 | +- **Explanation**: |
| 79 | + This is the beginning of the `Solution` class, which contains a public method called `kthLargest`. This method takes a vector of integers (`arr`) and an integer (`k`) as input. |
| 80 | + |
| 81 | +- **Example**: |
| 82 | + If `arr = [3, 2, 1]` and `k = 2`, we are finding the 2nd largest sum among all possible contiguous subarrays of `arr`. |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +```cpp |
| 87 | + priority_queue<int, vector<int>, greater<int>> pq; |
| 88 | +``` |
| 89 | + |
| 90 | +- **Explanation**: |
| 91 | + Here, we create a min-heap (priority queue) called `pq`. We use `greater<int>` as the third parameter to make it a min-heap, where the smallest element is always at the top. This min-heap will help us keep track of the top `k` largest sums. |
| 92 | + |
| 93 | +- **Example**: |
| 94 | + For `k = 2`, this heap will store the 2 largest sums as we find them. |
| 95 | + |
| 96 | + |
| 97 | + |
| 98 | +```cpp |
| 99 | + int n = arr.size(); |
| 100 | +``` |
| 101 | + |
| 102 | +- **Explanation**: |
| 103 | + We store the size of `arr` in the variable `n` for easy reference throughout the code. |
| 104 | + |
| 105 | +- **Example**: |
| 106 | + If `arr = [3, 2, 1]`, then `n = 3`. |
| 107 | + |
| 108 | + |
| 109 | + |
| 110 | +```cpp |
| 111 | + for(int i = 0; i < n; i++){ |
| 112 | +``` |
| 113 | +
|
| 114 | +- **Explanation**: |
| 115 | + This is the beginning of an outer loop, which iterates over each element in `arr`. The variable `i` represents the starting index of each subarray. |
| 116 | +
|
| 117 | +- **Example**: |
| 118 | + For `arr = [3, 2, 1]`, the outer loop will run 3 times with `i = 0`, `i = 1`, and `i = 2`. |
| 119 | +
|
| 120 | +
|
| 121 | +
|
| 122 | +```cpp |
| 123 | + int sum = 0; |
| 124 | +``` |
| 125 | + |
| 126 | +- **Explanation**: |
| 127 | + We initialize a variable `sum` to 0. This `sum` variable will store the cumulative sum of each subarray that starts at index `i`. |
| 128 | + |
| 129 | + |
| 130 | + |
| 131 | +```cpp |
| 132 | + for(int j = i; j < n; j++){ |
| 133 | +``` |
| 134 | +
|
| 135 | +- **Explanation**: |
| 136 | + This is the beginning of an inner loop, which iterates from the starting index `i` to the end of the array. The variable `j` represents the end index of the current subarray. |
| 137 | +
|
| 138 | +- **Example**: |
| 139 | + - If `i = 0`, `j` will take values `0, 1, 2`, representing subarrays `[3]`, `[3, 2]`, and `[3, 2, 1]`. |
| 140 | + - If `i = 1`, `j` will take values `1, 2`, representing subarrays `[2]` and `[2, 1]`. |
| 141 | +
|
| 142 | +
|
| 143 | +
|
| 144 | +```cpp |
| 145 | + sum += arr[j]; |
| 146 | +``` |
| 147 | + |
| 148 | +- **Explanation**: |
| 149 | + We add `arr[j]` to `sum`, updating the cumulative sum of the current subarray. |
| 150 | + |
| 151 | +- **Example**: |
| 152 | + - If `arr = [3, 2, 1]` and `i = 0`, the `sum` values in each inner loop iteration will be: |
| 153 | + - `j = 0`: `sum = 3` (subarray `[3]`) |
| 154 | + - `j = 1`: `sum = 5` (subarray `[3, 2]`) |
| 155 | + - `j = 2`: `sum = 6` (subarray `[3, 2, 1]`) |
| 156 | + |
| 157 | + |
| 158 | + |
| 159 | +```cpp |
| 160 | + if(pq.size() < k){ |
| 161 | + pq.push(sum); |
| 162 | +``` |
| 163 | +
|
| 164 | +- **Explanation**: |
| 165 | + Here, we check if the heap `pq` has fewer than `k` elements. If it does, we add `sum` to `pq`. |
| 166 | +
|
| 167 | +- **Example**: |
| 168 | + - For `k = 2`, if `pq` has less than 2 elements, we push the `sum` of each subarray directly. |
| 169 | +
|
| 170 | +
|
| 171 | +
|
| 172 | +```cpp |
| 173 | + } else { |
| 174 | + if(sum > pq.top()){ |
| 175 | + pq.pop(); |
| 176 | + pq.push(sum); |
| 177 | + } |
| 178 | + } |
| 179 | +``` |
| 180 | + |
| 181 | +- **Explanation**: |
| 182 | + If `pq` already has `k` elements, we check if `sum` is greater than the smallest element in `pq` (which is `pq.top()`). If it is, we pop the smallest element and push the current `sum` to ensure that `pq` contains the `k` largest sums found so far. |
| 183 | + |
| 184 | +- **Example**: |
| 185 | + For `k = 2`: |
| 186 | + - Suppose `pq` already contains `[3, 5]` and `sum = 6`. Since `6 > 3`, we pop `3` and push `6`, updating `pq` to `[5, 6]`. |
| 187 | + - If `sum = 4` comes up, it’s not greater than `pq.top()`, so we skip it. |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | +```cpp |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + return pq.top(); |
| 196 | +``` |
| 197 | + |
| 198 | +- **Explanation**: |
| 199 | + After both loops complete, the top element of `pq` (i.e., `pq.top()`) will be the `k`-th largest sum among all contiguous subarrays. This value is returned as the result. |
| 200 | + |
| 201 | +- **Example**: |
| 202 | + If `pq` contains `[5, 6]` after processing all subarrays for `k = 2`, `pq.top()` (which is `5`) is returned as the 2nd largest sum. |
| 203 | + |
| 204 | + |
| 205 | + |
| 206 | +### Step 3: Additional Example |
| 207 | + |
| 208 | +Let’s walk through the code with an example input to see how the heap changes. |
| 209 | + |
| 210 | +**Example** |
| 211 | +Input: `arr = [3, 2, 1]`, `k = 2` |
| 212 | + |
| 213 | +**Process**: |
| 214 | +1. **i = 0**: |
| 215 | + - **j = 0**: sum = 3 → `pq` is `[3]` |
| 216 | + - **j = 1**: sum = 5 → `pq` becomes `[3, 5]` |
| 217 | + - **j = 2**: sum = 6 → `6 > 3` → pop `3`, push `6` → `pq` becomes `[5, 6]` |
| 218 | + |
| 219 | +2. **i = 1**: |
| 220 | + - **j = 1**: sum = 2 → `2 < 5`, so `pq` remains `[5, 6]` |
| 221 | + - **j = 2**: sum = 3 → `3 < 5`, so `pq` remains `[5, 6]` |
| 222 | + |
| 223 | +3. **i = 2**: |
| 224 | + - **j = 2**: sum = 1 → `1 < 5`, so `pq` remains `[5, 6]` |
| 225 | + |
| 226 | +At the end, `pq` contains `[5, 6]`. Thus, `pq.top()`, which is `5`, is the 2nd largest sum. |
| 227 | + |
| 228 | + |
| 229 | + |
| 230 | +### Step 4: Time and Space Complexity |
| 231 | + |
| 232 | +1. **Time Complexity**: |
| 233 | + - Outer loop runs `n` times (for each starting index). |
| 234 | + - Inner loop runs up to `n` times. |
| 235 | + - Each insertion and removal in the heap takes `O(log k)`. |
| 236 | + - Therefore, total time complexity = `O(n^2 * log k)`. |
| 237 | + |
| 238 | +2. **Space Complexity**: |
| 239 | + - The heap size is at most `k`, so space complexity = `O(k)`. |
| 240 | + |
| 241 | + |
| 242 | +### Step 5: Additional Recommendations for Students |
| 243 | + |
| 244 | +1. **Practice with Min-Heaps**: Understanding how min-heaps work is essential, especially for maintaining top `k` elements. |
| 245 | +2. **Work with Sliding Windows**: This problem introduces a concept similar to sliding windows and cumulative sums, helpful in optimizing problems with subarrays. |
| 246 | +3. **Alternative Approach**: For very large arrays, advanced techniques like "prefix sums" could optimize finding subarray sums. |
| 247 | + |
| 248 | +This explanation should give you a solid foundation for understanding and implementing the solution for the Kth Largest Sum Contiguous Subarray problem. |
0 commit comments