153. Find Minimum in Rotated Sorted Array\229. Majority Element II\Moore's voting algorithm

本文介绍了解决两个经典算法问题的方法:在一个旋转过的有序数组中找到最小值,以及在一个整数数组中找到出现频率超过n/3的元素。提供了两种不同的解决方案,一种是简单的线性搜索,另一种则是利用二分查找或改进后的投票算法来达到更高效的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

153. Find Minimum in Rotated Sorted Array

题目描述

一个已经排好序的数组进行了旋转,然后找到最小的元素。

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.

代码实现

暴力法:复杂度O(n)

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len = nums.size();
        if(!len)  return 0;
        int res = nums[0];
        for(int i = 1; i < len; i++) if(res >= nums[i])  return nums[i];
        return res;
    }
};

使用二分法的话,那么就是log(N)。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int lo = 0, hi = nums.size() - 1, mid;
        while(lo < hi) {
            mid = (lo + hi) >> 1;
            if(nums[mid] > nums[hi])  lo = mid + 1;
            else hi = mid;
        }
        return nums[lo];
    }
};

229. Majority Element II

题目描述

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  • How many majority elements could it possibly have?
  • Do you have a better hint? Suggest it!

代码实现

原本题意是要求使用O(1)的space,这里我是用了O(n)的space。使用set实现。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        unordered_map<int, int> um;
        vector<int> res;
        int n = nums.size(), tar = floor(n/3);
        for(int i = 0; i < n; i++) {
            if(um.count(nums[i]) && um[nums[i]] != -1) {
                um[nums[i]]++;
                if(um[nums[i]] > tar) { res.push_back(nums[i]); um[nums[i]] = -1; }
            }
            else if(!um.count(nums[i])) {  
                um[nums[i]] = 1;
                if(um[nums[i]] > tar) { res.push_back(nums[i]); um[nums[i]] = -1; }
            }
        }
        return res;
    }
};

以上的方法明显不符合space O(1)的实现,所以在这里使用了一种叫做:Moore’s voting algorithm.

如果是超过半数以上的数是同一元素,那么就可以有以下实现:【2】

int majorityElement(vector<int> &num)
{
    int curIdx = 0, count = 1;
    for (int i = 1; i < num.size(); ++i)
    {
        num[i] == num[curIdx] ? ++count : --count;
        if (!count)
        {
            curIdx = i;
            count = 1;
        }
    }

    return num[curIdx];
}

使用同样的方法,leetcode上有个人做了大于n/k的通用做法:

class Solution {
private:    
    vector<int> majorityElement(vector<int>& nums, const int k) {
        const int size_n = nums.size();
        vector<int> result;
        unordered_map<int, int> cand;

        for (int i = 0; i < size_n; i++) {
            // 初始化的值都是0     
            cand[nums[i]]++;
            if (cand.size() == k) {
                // 每次存了k个数,就把只有一次的踢掉
                for (auto it = cand.begin(); it != cand.end(); ) {
                    if (--(it->second) == 0) it = cand.erase(it);
                    else it++;
                }
            }
        }
        // 把筛选之后的数据值置为0为接下来计算出现次数
        for (auto& item : cand) item.second = 0;
        for (auto& item : nums) 
            if (cand.count(item) > 0) cand[item]++;
        for (auto& item : cand) 
            if (item.second > size_n / k) result.emplace_back(item.first);
        return result;
    }
public:
    vector<int> majorityElement(vector<int>& nums) {
        return majorityElement(nums, 3);
    }
};

这种做法中map的存储数据大小是3个,所以可以认为是constant space。

参考资料:

【1】Moore’s voting algorithm: http://www.cs.utexas.edu/~moore/best-ideas/mjrty/
【2】超过半数的数字: http://blog.youkuaiyun.com/chfe007/article/details/42919017

在Python中,并没有一个内建函数或方法叫做`.minimum_rotated_rectangle`。不过,如果你是在图像处理或计算机视觉的上下文中提到这个术语,可能是你在使用某个库或框架时接触到的函数或方法,它用于计算并返回最小旋转矩形。 在OpenCV库中,可以使用`minAreaRect()`函数来找到给定点集的最小旋转矩形。这个函数返回一个`RotatedRect`对象,包含了旋转矩形的中心点、宽度、高度以及旋转角度。最小旋转矩形是能够覆盖所有点且面积最小的矩形。 以下是一个使用OpenCV实现最小旋转矩形的例子: ```python import cv2 import numpy as np # 假设points是一个二维点集,例如 [[x1, y1], [x2, y2], ..., [xn, yn]] points = np.array([[10, 10], [10, 30], [30, 30], [30, 10]], dtype=np.float32) # 使用minAreaRect函数计算最小旋转矩形 rect = cv2.minAreaRect(points) # 输出旋转矩形的中心点、尺寸和旋转角度 print("旋转矩形的中心点:", rect[0]) print("旋转矩形的尺寸:", rect[1]) print("旋转矩形的角度:", rect[2]) # 绘制旋转矩形 box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(image, [box], 0, (0, 255, 0), 2) ``` 在这段代码中,首先创建了一个点集`points`,然后使用`minAreaRect()`函数计算出最小旋转矩形。`rect[0]`是旋转矩形的中心,`rect[1]`是旋转矩形的尺寸(宽度和高度),`rect[2]`是旋转矩形的角度。最后,使用`boxPoints()`函数和`drawContours()`函数将旋转矩形绘制到图像上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值