leetcode-数据结构

今日第一题

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false

本来使用两个for循环解决,但是后面的测试题超时了
官方给出的答案如下:

利用快排后排序,检查相邻元素

int cmp(const void* _a, const void* _b) {
    int a = *(int*)_a, b = *(int*)_b;
    return a - b;
}

bool containsDuplicate(int* nums, int numsSize) {
    qsort(nums, numsSize, sizeof(int), cmp);
    for (int i = 0; i < numsSize - 1; i++) {
        if (nums[i] == nums[i + 1]) {
            return true;
        }
    }
    return false;
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/contains-duplicate/solution/cun-zai-zhong-fu-yuan-su-by-leetcode-sol-iedd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。`在这里插入代码片`

但自己写的快排过不了时间复杂度

int partition(int *arr,int low,int high){
    int pivot = arr[low];
    while(low < high){
        while(low < high && arr[high] >= pivot) --high;
        arr[low] = arr[high];
        while(low < high && arr[low] <= pivot) ++low;
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    return low; 
}

void QuickSort(int* arr, int low, int high){
    if(low < high){
        int pivotpos = partition(arr,low,high);
        QuickSort(arr,low,pivotpos-1);
        QuickSort(arr,pivotpos+1,high);
    }
}

bool containsDuplicate(int* nums, int numsSize){
    QuickSort(nums,0,numsSize-1);
    int i=0;
    for(i=0;i<numsSize-1;i++){
        if(nums[i] == nums[i+1])
            return true;
    }
    return false;
}

参考Java的答案中

优化选取中枢,三数取中(其他还有随机选取、九数取中、双pivot)

进行快排的优化:

int partition(int *arr,int low,int high){
        int temp;
        int m = low + (high - low) / 2;//三数取中
        if (arr[low] > arr[high]){
            temp = arr[low];
            arr[low] = arr[high];
            arr[high] = temp;
        }
        if (arr[m] > arr[high]){
            temp = arr[m];
            arr[m] = arr[high];
            arr[high] = temp;
        }
        if (arr[m] > arr[low]){
            temp = arr[m];
            arr[m] = arr[low];
            arr[low] = temp;
        }

    int pivot = arr[low];
    while(low < high){
        while(low < high && arr[high] >= pivot) --high;
        arr[low] = arr[high];
        while(low < high && arr[low] <= pivot) ++low;
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    return low; 
}

void QuickSort(int* arr, int low, int high){
    if(low < high){
        int pivotpos = partition(arr,low,high);
        QuickSort(arr,low,pivotpos-1);
        QuickSort(arr,pivotpos+1,high);
    }
}

bool containsDuplicate(int* nums, int numsSize){
    QuickSort(nums,0,numsSize-1);
    int i=0;
    for(i=0;i<numsSize-1;i++){
        if(nums[i] == nums[i+1])
            return true;
    }
    return false;
}

执行用时:140 ms, 在所有 C 提交中击败了5.74%的用户
内存消耗:12 MB, 在所有 C 提交中击败了85.74%的用户

第二题

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分

思考了三十分钟,一句代码没写出来,回到暴力法

int maxSubArray(int* nums, int numsSize){
//暴力试试
int max=-999;//最大值
int j=1;
int lenth=0;//逐步增大数组的可选空间
for(lenth=0;lenth<=numsSize;lenth++){
    //每次从第一个元素开始
    for(int i=0;i<numsSize-lenth;i++){
        int number=0;
        for(j=0;j<=lenth;j++){
            number+=nums[i+j];
        }
        if(number>=max){
            max=number;
        }
        }
    }
    return max;
}

最后依然是面对很大的数组时,超出时间限制,暴力法很难通过最后十个例子,果然时间复杂度很重要

官方解题思路:

f(i)=max{f(i−1)+nums[i],nums[i]}–动态规划

int maxSubArray(int* nums, int numsSize) {
    int pre = 0, maxAns = nums[0];
    for (int i = 0; i < numsSize; i++) {
        pre = fmax(pre + nums[i], nums[i]);
        maxAns = fmax(maxAns, pre);
    }
    return maxAns;
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode-solution/
来源:力扣(LeetCode)

你可能感兴趣的:(刷题日记,数据结构,leetcode,算法)