Code của cậu dài nên chắc khó hiểu, nên tớ refactor lại code chút, hi vọng dễ hiểu hơn 
boolean splitArray(int[] nums) {
return splitArrayHelper(0, nums, 0, 0);
}
boolean splitArrayHelper(int start, int[] nums, int group1, int group2) {
if(start >= nums.length) {
return group1 == group2;
}
return splitArrayHelper(start+1, nums, group1 + nums[start], group2) || splitArrayHelper(start+1, nums, group1, group2 + nums[start]);
}
Tớ đùa chút thôi 
Để giúp cậu hiểu cách hoạt động của đệ quy, tớ sẽ hỏi cậu 1 số câu hỏi, mục đích để cậu tự tìm câu trả lời. Tớ biết nó sẽ hơi tricky chút, nhưng mà nó sẽ có ích cho cậu sau này, vì đoạn code này dễ ơi là dễ. Vậy nên, kiên nhẫn, và thử giúp tớ trả lời mấy câu sau nha:
- Khi viết đệ quy, luôn có trường hợp cơ sở, định nghĩa khi nào đệ quy dừng lại được. Trường hợp cơ sở ở đây là gì?
- Ý nghĩa của các biến
start, nums, group1, group2 là gì? (cậu cần phân tích code để hiểu ý nghĩa của nó, tớ biết phần này sẽ khó, nhưng cậu đã có đề bài rồi mà
)
- Tại sao hàm
splitArrayHelper lại trả về boolean? Nó có ý nghĩa gì vậy?
- Ở dòng này:
splitArrayHelper(start+1, nums, group1 + nums[start], group2)
Tại sao lại truyền parameter start + 1 và group1 + nums[start]? Ý nghĩa của việc này là gì?
5. Ở dòng này:
splitArrayHelper(start+1, nums, group1, group2 + nums[start])
Tại sao lại truyền parameter start + 1 và group2 + nums[start]? Ý nghĩa của việc này là gì?
6. Tất cả các điều trên đóng góp như thế nào để giải quyết problem nêu ra ở đề bài?
Analyzing là kỹ năng quan trọng của 1 kỹ sư. Vậy nên tớ nghĩ đây là cơ hội tuyệt vời cho cậu để thực tập việc đó.
Nếu cậu không muốn trở thành kỹ sư, thì bảo tớ nha, tớ sẽ trả lời cho cậu 