分治法(C語言)leetcode 169,53,215
阿新 • • 發佈:2021-01-06
技術標籤:leetcode
169多數元素
給定一個大小為 n 的陣列,找到其中的多數元素。多數元素是指在陣列中出現次數 大於 ⌊ n/2 ⌋ 的元素。
你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。
來源:力扣(LeetCode)
int majorityElement(int* nums, int numsSize){
getmaj(nums, 0, numsSize-1);
}
int getmaj(int *nums, int low,int high)
{
int left,right;//記錄兩個邊的眾數
int i;
int countleft = 0, countright = 0;
if(low = high)//陣列中只有一個數
{
return nums[low];
}
else
{
mid = (low + high)/2;
left = getmaj(nums, low, mid);
right = getmaj(nums, mid+1, high);
if(left = right)//兩邊眾數相等
{
return left;
}
else{
for(i = 0; i <= high;)//if不相等遍歷整個陣列來看哪個比較多
{
if (num[i] == left)
{
countleft++;
}
if (num[i] == right)
{
countright++;
}
}
return countleft > countright? left:right;
}
}
}
時間複雜度O(nlogn)
53 maximum subarray
給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
int maxSubArray(int* nums, int numsSize){
maxsub(nums, 0, numsSize - 1);
}
int maxsub(*nums, int left, int right)
{
int max = 0;
int mid = 0;
int rightsum,leftsum;
int lefts = 0;
int rights = 0;
int s1,s2;
if (numsSize = 1)//只有1個數返回自己
{
return max = nums[0];
}
else
{
mid = (left + right)/2;
leftsum = maxsub(nums, left, mid);
rightsum = maxsub(nums, mid+1, right);
//跨中間情形
//分別從中間往兩邊遍歷
for(i = mid; i >= left; i--)
{
lefts = lefts + nums[i];
if(lefts > s1)
{
s1 = lefts;
}
}
for(i = mid + 1; i <= right; i++)
{
rights = rights + nums[i];
if(rights > s2)
{
s2 = rights;
}
}
if(s1 + s2 < leftsum && leftsum > rightsum)//左邊最大
{
return leftsum;
}
if(s1 +s2 < rightsum && leftsum < rightsum)//右邊最大
{
return rightsum;
}
if (s1 + s2 > leftsum && s1 + s2 >rightsum)//雙邊加起來最大
{
return s1 + s2;
}
}
}
時間複雜度O(nlogn)
215. 陣列中的第K個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
int findKthLargest(int* nums, int numsSize, int k){
int index=0;
if(k < numsSize || k > numsSize)//兩種越界,錯誤返回
{
return -1;
}
if(numsSize = 1)//只有1個數
{
return nums[0];
}
else
{
index = search(nums, 0, numsSize - 1);
if (index = numsSize-k)//隨機數剛好是第k大的數
{
return nums[index];
}
else
{
if(index < numsSize - k)//目標數要比pivot大,選擇右邊重新排序
{
search(nums, index+1,right);
}
elseif(index > numsSize - k)//目標數要比pivot小,選擇左邊重新排序
{
search(nums,left,index-1);
}
}
}
}
int search(int *nums, int left, int right)//快速排序知道pivot的位置
{
int pivot = nums[left];//最左邊位置為哨兵
for(; left != right; )//快速排序
{
for(;nums[right] > pivot;)
{
right--;
}
nums[left] = nums[right];
for(; nums[left] <= pivot;)
{
left++;
}
nums[right] = nums[left];
}
return left;
}
時間複雜度O(n)