Daily 08/06/2024: [523. Continuous Subarray Sum](https://leetcode.com/problems/continuous-subarray-sum/)
# 1. Tóm tắt đề bài
- Cho một mảng số nguyên ```nums``` và một số nguyên ```k```, trả về ```true``` nếu ```nums``` có **mảng con tốt** hoặc ```false``` nếu ngược lại .
- **Một mảng con tốt** là một mảng con trong đó:
- Chiều dài của nó ít nhất là 2 , và
- Tổng các phần tử của mảng con là bội số của k.
- **Lưu ý** rằng:
- Mảng con là phần liền kề của mảng.
- Một số nguyên ```x``` là bội số của ```k``` nếu tồn tại một số nguyên ```n``` sao cho ```x = n * k```. ```0``` luôn là bội số của ```k```.
#### Giới hạn
- $1 \le$ ```nums.length``` $\le 10^5$
- $1 \le$ ```nums[i]``` $\le 10^9$
- $0 \le$ ```sum(nums[i])``` $\le 2^{31} - 1$
- $1 \le$ ```k``` $\le 2^{31} - 1$
# 2. Tóm tắt lời giải
#### Phân tích
- Với hướng tiếp cận đầu tiên là chạy trâu thì chúng ta đơn giản là xét hết các khoảng xong tính tổng từng khoảng. Độ phức tạp là $O(n^3)$.
- Cải tiến khi chúng ta dùng prefix sum thì sẽ cải tiến xuống $O(n^2)$. Với những bạn mới thì có thể tham khảo ở đây [https://wiki.vnoi.info/algo/data-structures/prefix-sum-and-difference-array.md].
- Tiếp đến thì chúng ta sẽ phân tích là tổng chia hết cho ```k```. Thế thì chúng chỉ quan tâm tới số dư của nó chia ```k``` bằng 0 là được. Vậy thì ý tưởng cải tiến đơn giản hơn là kiểm tra số dư đó đã xuất hiện trong ```prefix sum``` chưa. Giả sử có ```prefix[l - 1]``` và ```prefix[r]``` cùng số dư thì theo tính chất cơ bản ```prefix[r] - prefix[l - 1]``` sẽ chia hết cho ```k```. Hay tổng các phần tử thừ l tới ```r``` sẽ chia hết cho ```k``` và trả về ```true```.
# 3. Lời giải chi tiết
#### Thuật toán
- Sử dụng Hash Table tùy theo ngôn ngữ bạn đọc sử dụng.
#### Code
```C#
public class Solution {
public bool CheckSubarraySum(int[] nums, int k) {
int prevSum = nums[0] % k;
int currSum = 0;
HashSet<int> prefixSum = new HashSet<int>();
for (int i = 1; i < nums.Length; i++)
{
currSum = (prevSum + nums[i]) % k;
if(currSum % k == 0 || prefixSum.Contains(currSum))
return true;
if(!prefixSum.Contains(prevSum))
prefixSum.Add(prevSum);
prevSum = currSum;
}
return false;
}
}
```
#### Độ phức tạp
$O(n)$.
# 4. Kết luận & gợi ý mở rộng
- Một bài cuối tuần khá nhẹ nhàng.
> Hãy dùng nghị lực và sự kiên trì để đánh bại mọi thứ.
###### #Hashtag: <span style='color: blue'>Brute Force, Hash Table</span>