leetCode587(凸包问题)

今天又学了一种新算法,主要是编程求解平面集合问题
题目描述如下
在这里插入图片描述
这个题目用到的算法我们称之为凸包算法,有很多种,单核心思想都是从一个点出发,找到以出发点开始最左或者最右的一条边。
利用的是向量的叉乘的大小找到下一个点的位置

    /*关键思想:利用向量的叉乘来判断点的位置*/
    int cross(vector<int> &p, vector<int> &q, vector<int> &r){
        return (q[0]-p[0])*(r[1]-q[1]) - (r[0]-q[0])*(q[1]-p[1]);
    }

然后以找到的点为出发点,继续找下一个点,直到最后找到的点是出发点的时候,说明已经围完了

全部代码如下

class Solution {
public:
    /*关键思想:利用向量的叉乘来判断点的位置*/
    int cross(vector<int> &p, vector<int> &q, vector<int> &r){
        return (q[0]-p[0])*(r[1]-q[1]) - (r[0]-q[0])*(q[1]-p[1]);
    }

    vector<vector<int>> outerTrees(vector<vector<int>>& trees) {
        int n = trees.size();

        //找出最下面的点,以最下面的点为出发点
        int bot = 0;
        for(int i = 0; i<n;i++){
            if(trees[i][1] < trees[bot][1]){
                bot = i;
            }
        }
        vector<vector<int>> res;
        vector<int> visit(n, 0);
        int  p = bot;
        do{
            int q = (p+1)%n;
            for(int i=0; i<n; i++){
                if(i!=p && cross(trees[p], trees[q], trees[i])<0){
                    q = i;
                }
            }
            visit[q] = 1;
            res.push_back(trees[q]);
            //找出在这条边上的其他点
            for(int i = 0; i<n; i++){
                if(i==p){
                    continue;
                }
                if(!visit[i] && cross(trees[p], trees[q], trees[i]) == 0){
                    visit[i] = 1;
                    res.push_back(trees[i]);
                    /*如果i到p点的距离大于q到p点的距离的话,将i更新为q*/
                    int r1 = (trees[q][0]-trees[p][0])*(trees[q][0]-trees[p][0])+(trees[q][1]-trees[p][1])*(trees[q][1]-trees[p][1]);
                    int r2 = (trees[i][0]-trees[p][0])*(trees[i][0]-trees[p][0])+(trees[i][1]-trees[p][1])*(trees[i][1]-trees[p][1]);
                    if(r1<r2){
                        q = i;
                    }   
                }
            }
            p = q;
        }while(p!=bot);
        return res;
    }
};


这个算法是最简单的凸包算法,当然还可以在进行优化,今天就先做到这吧,明天再看看优化的凸包算法
收获还是蛮大的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值