题目:有一个无序、元素个数为2n的正整数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近?
1 1 2 -> 1 1 vs 2
看题时,解法的时间复杂度一般都大于或等于O(n^2)。突然灵感一闪,发现一个新的解法,应该算是一个动态规划的过程吧,思路比较简单,请看代码。空间复杂度O(nlogn),时间复杂度O(n)。但是不能确定是否适用所有正整数组,如果有错,请给出你的测试用例,谢谢!
代码如下:
1 1 #include <iostream> 2 2 #include <vector> 3 3 using namespace std; 4 4 5 5 int compare(const void *in_iLeft, const void *in_iRight) { 6 6 int *a = (int*) in_iLeft; 7 7 int *b = (int*) in_iRight; 8 8 return *a - *b ; 9 9 10 10 } 11 11 int main() { 12 12 vector<int> t_Vec; 13 13 int t_ivalue; 14 14 int t_iLen = 0; 15 15 cin >> t_ivalue; 16 16 while(t_ivalue != 0) { //输入为0,则停止输入 17 17 t_Vec.push_back(t_ivalue); 18 18 t_iLen ++; 19 19 cin >> t_ivalue; 20 20 21 21 } 22 22 int* t_pArr = new int[t_iLen]; 23 23 for(int i = 0; i < t_iLen; i++) { 24 24 t_pArr[i] = t_Vec[i]; 25 25 } 26 26 qsort(t_pArr, t_iLen, sizeof(int), compare); 27 27 int* t_pLeftArr = new int[t_iLen]; 28 28 int* t_pRightArr = new int[t_iLen]; 29 29 memset(t_pLeftArr, 0, t_iLen); 30 30 memset(t_pRightArr, 0, t_iLen); 31 31 int t_iSumLeft = t_pArr[t_iLen-1]; 32 32 int t_iSumRight = t_pArr[t_iLen-2]; 33 33 int t_iLeftIter = 1; 34 34 int t_iRightIter = 1; 35 35 t_pLeftArr[0] = t_pArr[t_iLen-1]; 36 36 t_pRightArr[0] = t_pArr[t_iLen-2]; 37 37 for(int i = t_iLen - 3; i >= 0 ; i --) { 38 38 if(t_iSumLeft < t_iSumRight) { 39 39 if(t_pArr[i] > 0) { 40 40 t_pLeftArr[t_iLeftIter ++] = t_pArr[i]; 41 41 t_iSumLeft += t_pArr[i]; 42 42 }else { 43 43 t_pRightArr[t_iRightIter ++] = t_pArr[i]; 44 44 t_iSumRight += t_pArr[i]; 45 45 } 46 46 }else { 47 47 if(t_pArr[i] > 0) { 48 48 t_pRightArr[t_iRightIter ++] = t_pArr[i]; 49 49 t_iSumRight += t_pArr[i]; 50 50 }else { 51 51 t_pLeftArr[t_iLeftIter ++] = t_pArr[i]; 52 52 t_iSumLeft += t_pArr[i]; 53 53 } 54 54 } 55 55 } 56 56 cout << "打印原序列:"<< endl; 57 57 for(int i = 0; i < t_iLen; i ++) { 58 58 if(t_pArr[i] != 0) { 59 59 cout << t_pArr[i] << " "; 60 60 }else { 61 61 break; 62 62 } 63 63 } 64 64 cout << endl; 65 65 66 66 cout << "打印第一个序列:"; 67 67 for(int i = 0; i < t_iLeftIter; i ++) { 68 68 if(t_pLeftArr[i] != 0) { 69 69 cout << t_pLeftArr[i] << " "; 70 70 }else { 71 71 break; 72 72 } 73 73 } 74 74 cout << endl; 75 75 cout << "第一个序列合为:" << t_iSumLeft << endl; 76 76 77 77 cout << "打印第二个序列:"; 78 78 for(int i = 0; i < t_iRightIter; i ++) { 79 79 if(t_pRightArr[i] != 0) { 80 80 cout << t_pRightArr[i] << " "; 81 81 }else { 82 82 break; 83 83 } 84 84 } 85 85 cout << endl; 86 86 cout << "第二个序列合为:" << t_iSumRight << endl; 87 87 t_Vec.clear(); 88 88 delete[] t_pArr; 89 89 delete[] t_pLeftArr; 90 90 delete[] t_pRightArr; 91 91 system("pause"); 92 92 return 0; 93 93 94 94 95 95 }
但是如果题目改成任意整数时你该怎么解答了呢? :)
时间: 2024-10-25 13:41:47