分治法(C语言)leetcode 169,53,215

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)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值