VERY INFORMATIVE PROBLEM: LEETCODE - 1920
https://leetcode.com/problems/build-array-from-permutation/description/?envType=daily-question&envId=2025-05-06
KEY QUESTION
Follow-up: Can you solve it without using an extra space (i.e., O(1) memory)?
THE PROCESS OF THINKING FROM GPT
You're absolutely right — and your thinking is **logical and common** when first tackling O(1) space problems.
Let’s break this down carefully and **bridge the gap** between your current intuition and the idea of "storing two values in one slot":
---
### ✅ What O(1) Memory Really Means in Leetcode
When a problem says **O(1) extra space**, it means:
> You can’t use **extra data structures** whose size depends on `n` — like arrays, vectors, hashmaps, etc.
But you **can use:**
* A few variables (e.g., `int`, `bool`, `index`, etc.)
* The **input array itself**, if you don't need to preserve its original values
---
### 🧠 Why You Might Miss the “Store Two in One” Trick
That trick feels **unnatural at first** because:
* It sounds like you're modifying the original data and maybe losing it
* It’s not something we normally do unless we're explicitly taught
But here’s a way to help you come up with it yourself in the future:
---
### 🪜 Easier Way to Discover It — Step-by-Step Intuition
Let’s pretend you're solving the problem and want to avoid extra space:
1. You try a brute force:
```cpp
for (int i = 0; i < n; i++) {
ans[i] = nums[nums[i]]; // can't do this in-place
}
```
You realize this **needs a new array** → not allowed.
2. You wonder: Can I **reuse `nums`**?
But if I overwrite `nums[i]`, I lose the original — which I still need later.
3. Now you think:
> Can I “store” the new value **somehow** without losing the old one?
4. Then you might try:
> If all values are less than `n`, maybe I can do some math to hide both…
That’s when the idea of:
```cpp
nums[i] = nums[i] + n * (nums[nums[i]] % n)
```
might naturally come to you — **not as a formula**, but as a strategy to “hide” a second number using **multiples of `n`**.
---
### 🎯 Key Trick to Remember:
If the values in an array are **bounded** (like `< n`), you can often **hide additional information** using:
* Modulo: to keep the original
* Division: to extract what you stored
---
### 🧩 Analogy
Imagine each `nums[i]` is a little box that can store a number up to 99.
If you're told:
> All values are ≤ 9
Then you can use base 10 to store:
* old = 4
* new = 7
→ `nums[i] = 4 + 10 * 7 = 74`
You can recover:
* `nums[i] % 10 = 4`
* `nums[i] / 10 = 7`
---
### ✅ Conclusion:
You're correct that **O(1) memory** includes using constants like two `int`s — but sometimes, problems let you **reuse the input array** in clever ways.
**Next time, ask yourself:**
> Can I encode more than one thing inside each element, if values are small?
This is the pattern. Once you know this strategy, you’ll start to **recognize when it can be applied**.
Would you like a list of similar problems where this trick is useful for practice?
MY CONCLUSION
the key insight is:
- we should try not to use any extra mem space, rather than constant mem space, like countable vars.
- the first hint tell us we should save original value and result value in the original array.
- to achieve that, we can set the value
a + n * bto the designated index of array, if and only if a < n. if the element has specific limit, you should pay attention to if b is less than n or which may cause the result overflow. - when decoding, we get the original a from
nums[i] % n. we get the original b fromnums[i] / n.
MY SOLUTION
class Solution {
public:
vector<int> buildArray(vector<int>& nums) {
for (int i = 0; i < nums.size(); i++) {
int encoded_val = nums[i];
int origin_val = encoded_val % nums.size(); // < n
int ans = nums[origin_val] % nums.size(); // < n
nums[i] = origin_val + nums.size() * ans;
}
for (int i = 0; i < nums.size(); i++) {
nums[i] = nums[i] / nums.size();
}
return nums;
}
};
本文来自博客园,作者:ijpq,转载请注明原文链接:https://www.cnblogs.com/ijpq/p/18863326

浙公网安备 33010602011771号