本体的一个直观想法是,使用二重循环枚举序列中的整数 a 和 b ,判断它们的和是否为 M,如果是,输出方案;如果不是,则继续枚举。
解题代码:
1 2 3 4 5 6 7 8
voidfun(int a[], int n, int M){ int i, j; for (i = 0; i < n; i++){ for (j = i + 1; j < n; j++){ if (a[i] + a[j] == M) printf("%d %d\n", a[i], a[j]); } } }
voidfun(int a[], int n, int M){ int i, j; for (i = 0, j = n - 1; i < j; ){ if (a[i] + a[j] > M) j--; elseif (a[i] + a[j] < M) i++; else{ printf("%d %d", i, j); i++; j--; } } }
该算法的时间复杂度为 o(n) ,比暴力的二重循环法优秀很多。
序列合并问题
假设由两个递增序列 A 和 B ,要求把它们合并为一个递增序列 C 。
解题思路:
令 i = 0 , j = 0 ,分别指向两个序列的第一个元素。
当 i, j 都没有到达序列的末端时,
若 A[i] < B [i] ,将 A[i] 加入 C , i 自增。
若 A[i] > B [i] ,将 B[j] 加入 C , j 自增。
若 A[i] == B [i] ,任选一个加入 C ,对应下标自增。
将剩余元素的序列中所有剩余元素依次放入 C 中。
解题代码:
1 2 3 4 5 6 7 8 9 10 11
intMerge(int A[], int B[], int C[], int n, int m){ int i, j, k; i = j = k = 0; while (i < n && j < n){ if (A[i] <= B[j]) C[k++] = A[i++]; else C[k++] = A[j++]; } while (j < n) C[k++] = A[j++]; while (i < n) C[k++] = A[i++]; return k; //返回C的长度 }
voidQuickSort(int A[],int low, int high){ if (low < high){ int flag = Partition(A, low, high); QuickSort(A,low, flag - 1); QuickSort(A,flag + 1, high); } }