
# Search : Beautiful Array
Một mảng được gọi là “đẹp” nếu mảng đó chứa một phần tử mà phần tử đó chia mảng làm 2 phần (không rỗng và không chứa phần tử đó) có tổng bằng nhau.
Hãy kiểm tra xem một mảng bất kì có phải là một mảng “đẹp” hay không?
Ví dụ:
- Với
a = [1, 2, 3]
thì kết quảbeautifulArray(a) = false
- Với
a = [1, 2, 3, 3]
đầu ra của chương trình sẽ làbeautifulArray(a) = true
Chọn phần tử ở vị trí thứ3
(tính từ trái sang), thì mảng ban đầu được chia thành 2 phần[1,2]
và[3]
có tổng 2 phần bằng nhau
Đầu vào/Đầu ra
-
[Thời gian chạy] 1 giây
-
[Đầu vào] Array.integer a
0 <= a.length <= 10000
-
[Đầu ra] Boolean
Lý thuyết
Mảng cộng dồn
- Bài toán: Cho trước một dãy số
A
. Tính tổng:A[L]+A[L+1]+...+A[R-1]+A[R]
- Ở bài toán này thông thường ta sẽ mất một chi phí là
O(R-L+1)
để xét các số từL
đếnR
và cộng vào kết quả. Nhưng với “mảng cộng dồn” ta chỉ cần chuẩn bị trongO(A.size())
và lấy kết quả trong độ phức tạp làO(1)
.
- Ở bài toán này thông thường ta sẽ mất một chi phí là
- Định nghĩa :
S
được gọi là “mảng cộng dồn” của dãyA
nếuS[i] = A[1]+A[2]+...+A[i]
với mọi0 <= i < A.size())
- Áp dụng:
A[L]+A[L+1]+...+A[R]
=(A[0]+A[1]+...+A[R]) - (A[1]+A[2]+...+A[L-1])
=S[R]-S[L-1]
.- Từ biểu thức trên, ta thấy rằng thay vì ta phải xét toàn bộ các phần tử từ
L→R
trong mảngA
, ta chỉ cần quan tâm đến 2 phần từS[R]
vàS[L-1]
trong “mảng cộng dồn”.
- Miêu tả thuật toán:
- Với
i=0
:S[i]
=A[i]
- Với
i≥0
:S[i]
=A[1]+A[2]+...+A[i]
=(A[1]+A[2]+...+A[i-1])+A[i]
=S[i-1]+A[i]
/// Xây dựng mảng cộng dồn S vector<int> Build(vector<int> A) { S.resize(A.size()); for (int i = 0; i < (int) A.size(); ++i) { if (i == 0) S[i] = A[i]; else S[i] = S[i-1] + A[i]; } return S; } /// Tính tổng các số thuộc đoạn [L,R] của mảng A int getSum(vector<int> A, int L, int R) { vector<int> S = Build(A); if (L == 0) return S[R]; return S[R] - S[L-1]; }
- Với
Hướng dẫn bài tập.
Code mẫu:
Ngôn ngữ C++:
bool beautifulArray(std::vector<int> arr)
{
std::vector<int> s;
s.push_back(arr[0]);
for (int i = 1; i < arr.size(); i++)
s.push_back(s[i-1] + arr[i]);
for (int i = 1; i < arr.size() - 1; i++)
if (s[i-1] == s.back() - s[i])
return true;
return false;
}
Post Comment