目录
一、问题描述
二、蛮力枚举思路
1.初始化:
2.遍历所有可能的四元组:
3.检查和:
4.避免重复:
5.更新计数器:
三、代码实现
四、运行结果
五、 算法复杂度分析
一、问题描述
给定一个整数数组 nums,编写一个函数,找出所有和为0的四元组。你可以不考虑答案的顺序。如:nums = [-1, 0, 1, 2, -1, -4],输出:[-1,-1,0,2]等。
二、蛮力枚举思路
1.初始化:
创建一个二维数组rec来存储已经找到的和为0的四元组,以避免重复打印。同时,使用一个计数器count来记录已经找到的四元组的数量。
2.遍历所有可能的四元组:
使用四层嵌套循环来遍历数组中的所有可能的四个元素的组合。每一层循环分别选择一个元素,确保选择的元素是唯一的(即不重复选择同一个元素,也不选择之前已经选择过的元素位置之后的元素)。
3.检查和:
对于每一组通过四层循环选出的四个元素,计算它们的和。如果和等于0,则进一步检查这组元素是否已经记录在rec数组中。
4.避免重复:
通过遍历rec数组,检查当前找到的四元组是否已经存在。如果存在,则跳过这组元素;如果不存在,则将其添加到rec数组中,并打印出来。
5.更新计数器:
每当找到一个新的和为0的四元组时,更新count计数器的值。
三、代码实现
#include <stdio.h>
#include <stdlib.h> // 假设MAX是一个足够大的宏定义,用于指定rec数组的大小
#define MAX 1000 // 根据实际情况调整这个值// 定义一个比较函数,用于qsort排序(此函数应在代码中定义,但在此省略)
int compare(const void* a, const void* b) {return (*(int*)a - *(int*)b);
}// 找出所有和为0的四元组并打印
void num4sum0(int arr[], int N) {int rec[MAX][4] = { 0 }; // 用于存储已找到的四元组,避免重复打印int count = 0; // 记录已找到的四元组数量// 使用四层嵌套循环遍历所有可能的四元组for (int i = 0; i < N - 3; i++) {for (int j = i + 1; j < N - 2; j++) {for (int k = j + 1; k < N - 1; k++) {for (int l = k + 1; l < N; l++) {// 检查当前四元组的和是否为0if (arr[i] + arr[j] + arr[k] + arr[l] == 0) {int flag = 0; // 标记当前四元组是否已记录// 检查当前四元组是否已存在于rec数组中for (int a = 0; a < count; a++) { // 注意:应使用< count而非<= countif (rec[a][0] == arr[i] && rec[a][1] == arr[j] && rec[a][2] == arr[k] && rec[a][3] == arr[l]) {flag = 1;break;}}// 如果当前四元组未记录,则添加到rec数组并打印if (flag == 0) {rec[count][0] = arr[i];rec[count][1] = arr[j];rec[count][2] = arr[k];rec[count][3] = arr[l];printf("%d: %d %d %d %d\n", count, arr[i], arr[j], arr[k], arr[l]);count++; // 更新已找到的四元组数量}}}}}}
}int main() {//int arr[] = { -1, 0, 1, 2, -1, -4 };int arr[] = { -23, 45, -12, 7, 38, -41, 19, -6, 22, -34, 49, -7, 27, -29, 11, 3, -7, 28, 14, -9 };int N = sizeof(arr) / sizeof(int); // 计算数组长度// 使用qsort对数组进行排序qsort(arr, N, sizeof(int), compare);// 查找并打印所有和为0的四元组num4sum0(arr, N);return 0;
}
四、运行结果
五、 算法复杂度分析
算法的时间复杂度为O(N^4),蛮力枚举的方法虽然简单直观,但它的时间复杂度非常高,为O(N^4),其中N是数组的长度。这意味着当数组很大时,算法的执行时间将非常长,可能变得不可接受。可以先对数组进行排序,然后使用双指针法来减少时间复杂度-下次更新。