|
| 1 | +<h1 align="center">Longest - Arithmetic - Subsequence of - Given Difference</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Longest Arithmetic Subsequence of Given Difference](https://leetcode.com/problems/longest-arithmetic-subsequence-of-given-difference/description/) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +### Problem Explanation |
| 10 | +The problem is titled **"Longest Arithmetic Subsequence of Given Difference"**. The goal is to find the length of the longest subsequence of a given array such that the difference between consecutive elements of the subsequence is a constant value `difference`. |
| 11 | + |
| 12 | +#### **Definition of the Problem:** |
| 13 | +Given an array `arr` and an integer `difference`, the task is to find the length of the longest subsequence of `arr` where the difference between every two consecutive elements is exactly equal to `difference`. |
| 14 | + |
| 15 | +**Subsequence**: A subsequence is derived by deleting some or none of the elements of the array, without changing the order of the remaining elements. |
| 16 | + |
| 17 | +**Example**: |
| 18 | + |
| 19 | +- Input: |
| 20 | + ``` |
| 21 | + arr = [1, 5, 7, 8, 5, 3, 4, 2, 1], difference = 2 |
| 22 | + ``` |
| 23 | + |
| 24 | +- **Explanation**: |
| 25 | + We need to find the longest subsequence where the difference between consecutive elements is `2`. |
| 26 | + |
| 27 | + One possible subsequence is: |
| 28 | + ``` |
| 29 | + [1, 3, 5, 7] → (difference between consecutive elements is 2) |
| 30 | + ``` |
| 31 | + This is a subsequence with a length of 4, and there is no longer subsequence with the given difference. |
| 32 | + |
| 33 | +- **Output**: |
| 34 | + ``` |
| 35 | + 4 |
| 36 | + ``` |
| 37 | + |
| 38 | +The goal is to output the length of the longest such subsequence. |
| 39 | + |
| 40 | +### Approach to the Code: |
| 41 | + |
| 42 | +The approach used in the given solution leverages **dynamic programming (DP)** and **hash maps (unordered_map)** to store the length of the longest subsequences with specific differences. |
| 43 | + |
| 44 | +#### Steps: |
| 45 | + |
| 46 | +1. **Initialize a HashMap `dp`**: |
| 47 | + - `dp` will store the longest subsequence length for each possible number in the array, based on the given difference. |
| 48 | + - The key in the map is the number itself, and the value is the length of the longest subsequence ending at that number. |
| 49 | + |
| 50 | +2. **Iterate Through Each Element**: |
| 51 | + - For each element `arr[i]`, compute the `temp` value, which is `arr[i] - difference`. This is the value that would precede `arr[i]` in an arithmetic subsequence with the given `difference`. |
| 52 | + |
| 53 | +3. **Check if a Valid Subsequence Exists**: |
| 54 | + - If `temp` is present in the map `dp`, it means that there is an arithmetic subsequence ending with `temp`. In this case, the subsequence can be extended by adding `arr[i]`, so the length of the subsequence ending at `arr[i]` is `dp[temp] + 1`. |
| 55 | + - If `temp` is not found in the map, we initialize the subsequence ending at `arr[i]` with length `1` (it is a subsequence of just itself). |
| 56 | + |
| 57 | +4. **Update the DP Map**: |
| 58 | + - After determining the length of the subsequence ending at `arr[i]`, update the map `dp[arr[i]]` to the new length. |
| 59 | + |
| 60 | +5. **Track the Maximum Length**: |
| 61 | + - Keep track of the maximum subsequence length found so far using the variable `ans`. |
| 62 | + |
| 63 | +6. **Return the Result**: |
| 64 | + - Once all elements have been processed, the variable `ans` holds the length of the longest subsequence with the given difference. |
| 65 | + |
| 66 | +## Problem Solution |
| 67 | +```cpp |
| 68 | +class Solution { |
| 69 | +public: |
| 70 | + // Function to find the length of the longest arithmetic subsequence with the given difference |
| 71 | + int longestSubsequence(vector<int>& arr, int difference) { |
| 72 | + int n = arr.size(); // Get the size of the input array |
| 73 | + unordered_map<int, int> dp; // Map to store the longest subsequence length for each element |
| 74 | + |
| 75 | + int ans = 0; // Variable to store the maximum length of any subsequence found so far |
| 76 | + |
| 77 | + // Iterate through each element of the array |
| 78 | + for(int i = 0; i < n; i++) { |
| 79 | + // Calculate the previous element in the subsequence with the given difference |
| 80 | + int temp = arr[i] - difference; |
| 81 | + |
| 82 | + // If there's a subsequence ending with `temp`, we get its length from dp. If not, set prevAns to 0 |
| 83 | + int prevAns = dp.count(temp) ? dp[temp] : 0; |
| 84 | + |
| 85 | + // Update the longest subsequence ending at arr[i], adding 1 to the length of the previous subsequence |
| 86 | + dp[arr[i]] = 1 + prevAns; |
| 87 | + |
| 88 | + // Update the maximum subsequence length found so far |
| 89 | + ans = max(ans, dp[arr[i]]); |
| 90 | + } |
| 91 | + |
| 92 | + // Return the maximum length of the subsequence found |
| 93 | + return ans; |
| 94 | + } |
| 95 | +}; |
| 96 | +``` |
| 97 | + |
| 98 | +## Problem Solution Explanation |
| 99 | + |
| 100 | +```cpp |
| 101 | +int longestSubsequence(vector<int>& arr, int difference) { |
| 102 | + int n = arr.size(); |
| 103 | + unordered_map<int, int> dp; |
| 104 | + int ans = 0; |
| 105 | +``` |
| 106 | +- `n = arr.size()`: The length of the input array `arr` is stored in `n`. |
| 107 | +- `unordered_map<int, int> dp`: This hash map will store the length of the longest subsequence for each number as a key. |
| 108 | +- `int ans = 0`: This variable will hold the maximum length of the subsequence found. |
| 109 | +
|
| 110 | +```cpp |
| 111 | + for(int i = 0; i < n; i++){ |
| 112 | + int temp = arr[i] - difference; |
| 113 | + int prevAns = dp.count(temp) ? dp[temp] : 0; |
| 114 | +``` |
| 115 | +- The loop iterates through each element `arr[i]` of the array. |
| 116 | +- `int temp = arr[i] - difference`: For each `arr[i]`, the value `temp` is the number that would precede it in the subsequence (i.e., `arr[i] - difference`). |
| 117 | +- `int prevAns = dp.count(temp) ? dp[temp] : 0`: If `temp` is found in the map `dp`, we fetch the value `dp[temp]`, which is the length of the longest subsequence ending at `temp`. If `temp` is not found, `prevAns` is initialized to `0` because no subsequence exists ending with `temp`. |
| 118 | + |
| 119 | +```cpp |
| 120 | + dp[arr[i]] = 1 + prevAns; |
| 121 | + ans = max(ans, dp[arr[i]]); |
| 122 | + } |
| 123 | +``` |
| 124 | +- `dp[arr[i]] = 1 + prevAns`: Update the length of the longest subsequence ending at `arr[i]`. If `temp` exists in `dp`, we extend the subsequence by 1. Otherwise, the subsequence only consists of `arr[i]` itself, so the length is `1`. |
| 125 | +- `ans = max(ans, dp[arr[i]])`: Update the maximum length `ans` with the longest subsequence found so far. |
| 126 | + |
| 127 | +```cpp |
| 128 | + return ans; |
| 129 | +} |
| 130 | +``` |
| 131 | +- Finally, return `ans`, which holds the length of the longest subsequence with the given difference. |
| 132 | + |
| 133 | +### Example Walkthrough: |
| 134 | + |
| 135 | +#### Example 1: |
| 136 | +- **Input**: |
| 137 | + ``` |
| 138 | + arr = [1, 5, 7, 8, 5, 3, 4, 2, 1] |
| 139 | + difference = 2 |
| 140 | + ``` |
| 141 | + |
| 142 | +1. **First iteration (i = 0)**: |
| 143 | + - `arr[i] = 1` |
| 144 | + - `temp = 1 - 2 = -1` |
| 145 | + - `dp[-1]` doesn't exist, so `prevAns = 0`. |
| 146 | + - `dp[1] = 1 + 0 = 1`. |
| 147 | + |
| 148 | +2. **Second iteration (i = 1)**: |
| 149 | + - `arr[i] = 5` |
| 150 | + - `temp = 5 - 2 = 3` |
| 151 | + - `dp[3]` doesn't exist, so `prevAns = 0`. |
| 152 | + - `dp[5] = 1 + 0 = 1`. |
| 153 | + |
| 154 | +3. **Third iteration (i = 2)**: |
| 155 | + - `arr[i] = 7` |
| 156 | + - `temp = 7 - 2 = 5` |
| 157 | + - `dp[5]` exists and has value `1`, so `prevAns = 1`. |
| 158 | + - `dp[7] = 1 + 1 = 2`. |
| 159 | + |
| 160 | +4. **Fourth iteration (i = 3)**: |
| 161 | + - `arr[i] = 8` |
| 162 | + - `temp = 8 - 2 = 6` |
| 163 | + - `dp[6]` doesn't exist, so `prevAns = 0`. |
| 164 | + - `dp[8] = 1 + 0 = 1`. |
| 165 | + |
| 166 | +5. **Subsequent iterations** follow the same logic, and `dp` gradually accumulates the lengths of valid subsequences. |
| 167 | + |
| 168 | +- After processing all elements, the final answer is `4`, corresponding to the subsequence `[1, 3, 5, 7]`. |
| 169 | + |
| 170 | +#### **Output**: |
| 171 | +``` |
| 172 | +4 |
| 173 | +``` |
| 174 | + |
| 175 | +### Time and Space Complexity Analysis: |
| 176 | + |
| 177 | +- **Time Complexity**: |
| 178 | + - The algorithm iterates through the array once, and for each element, it performs constant-time operations (hash map lookups, insertions, and updates). |
| 179 | + - Thus, the time complexity is **O(n)**, where `n` is the number of elements in the array. |
| 180 | + |
| 181 | +- **Space Complexity**: |
| 182 | + - We use a hash map `dp` to store the longest subsequence length for each element. In the worst case, all elements in the array could have distinct differences, so the space used by the hash map is **O(n)**. |
| 183 | + - Therefore, the space complexity is **O(n)**. |
0 commit comments