Idea
You want the final list to be a palindrome, using the minimum number of merges of adjacent piles.
At any moment compare:
- left pile sum
- right pile sum
Rules
- If left == right, move both pointers inward (no merge needed)
- If left < right, merge left pile with the next pile to the right (one merge)
- If left > right, merge right pile with the previous pile to the left (one merge)
Why this works:
- To make a palindrome, the two ends must eventually match
- If one side is smaller, the only way to possibly match the other side is to grow that smaller side by merging inward
- Greedy is optimal here
C Solution
int minMergesToPalindrome(int a[], int n) {
int i = 0, j = n - 1;
int merges = 0;
while (i < j) {
if (a[i] == a[j]) {
i++;
j--;
} else if (a[i] < a[j]) {
// Merge a[i] with a[i+1]
a[i + 1] = a[i] + a[i + 1];
i++;
merges++;
} else {
// Merge a[j] with a[j-1]
a[j - 1] = a[j] + a[j - 1];
j--;
merges++;
}
}
return merges;
}
int main() {
int n;
scanf("%d", &n);
int a[1000];
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int result = minMergesToPalindrome(a, n);
printf("%d\n", result);
return 0;
}
Example
Input:
8
1 2 2 5 1 3 1 1
Output:
3
Time Complexity
- O(n)
- Each pointer moves inward, and each merge reduces the active number of piles.
Space Complexity
- O(1) extra space (in place)