滑动窗口,在所有出现的值中间移动,并且要去除重复出现的数
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_NUMS 180000
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
// 获得最大值和最小值,并且得到所有出现的数
void getRange(int* left, int* right, int** nums, int numsSize, int* numsColSize, int all[MAX_NUMS], int* allSize)
{
int i, j;
*left = INT_MAX;
*right = INT_MIN;
int tmp[MAX_NUMS] = {0};
int tmpSize = 0;
for (i = 0; i < numsSize; i++) {
*left = *left < nums[i][0] ? *left : nums[i][0];
*right = *right > nums[i][numsColSize[i] - 1] ? *right : nums[i][numsColSize[i] - 1];
for (j = 0; j < numsColSize[i]; j++) {
tmp[tmpSize] = nums[i][j];
tmpSize += 1;
}
}
qsort(tmp, tmpSize, sizeof(int), compare);
all[*allSize] = tmp[0]; // 去重
*allSize += 1;
for (i = 1; i < tmpSize; i++) {
if (tmp[i] != tmp[i - 1]) {
all[*allSize] = tmp[i];
*allSize += 1;
}
}
}
bool contain(int left, int right, int** nums, int numsSize, int* numsColSize)
{
int i, j;
bool flag = false;
for (i = 0; i < numsSize; i++) {
flag = false;
if (left > nums[i][numsColSize[i] - 1] || right < nums[i][0]) {
return false;
}
for (j = 0; j < numsColSize[i]; j++) {
if (nums[i][j] >= left && nums[i][j] <= right) {
flag = true;
break;
}
}
if (!flag) {
return false;
}
}
return true;
}
// 滑动窗口在所有出现的值中间移动,并且要去除重复出现的数
int* smallestRange(int** nums, int numsSize, int* numsColSize, int* returnSize){
*returnSize = 2;
int* result = (int*)malloc(sizeof(int) * 2);
if (result == NULL) {
return NULL;
}
int all[MAX_NUMS] = {0}; // 所有出现的数,不能重复
int allSize = 0;
int i, j;
int left, right;
getRange(&left, &right, nums, numsSize, numsColSize, all, &allSize);
result[0] = left;
result[1] = right;
// 在所有出现的数中间滑动
for (i = 0, j = 0; j < allSize; j++) {
while (i <= j && contain(all[i], all[j], nums, numsSize, numsColSize)) {
if ((all[j] - all[i]) < (result[1] - result[0]) || ((all[j] - all[i]) == (result[1] - result[0]) && (all[j] < result[1]))) {
result[0] = all[i];
result[1] = all[j];
}
i++;
}
}
return result;
}