今日第一题
给你一个整数数组 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)