力扣集训第三天

1232缀点成线

解题思路

通过画图可以看出,只要任意一点和其他所有点连线不在一条直线上,即可return false;
其次,为了判断何时直线平行与y轴,进行了flag标记,只有flag相同且k相同才可以返回true;反之就会返回false;
因为只有这种情况无法计算k值(分母为0)

代码

class Solution {
public:
    bool checkStraightLine(vector<vector<int>>&amp; coordinates) {
        //只需要任意一个点和其他所有点建立连线的斜率都相等,就可以满足,反之return false;
        int x0 = coordinates[0][0];
        int y0 = coordinates[0][1];
        double k0 = 0;double k1 = 0;int flag0 = 0;int flag1 = 0;
            if(coordinates[1][0] - x0 == 0){
                //此时用k来记录到y轴的距离;
                k0 = x0;flag0 = 1;
            }else{
                k0 = (coordinates[1][1] - y0)* 1.0 / (coordinates[1][0] - x0);
            }
        for(int i = 2;i<coordinates.size();i++){
            flag1 = 0;
            if(coordinates[i][0] - x0 == 0){
                //此时用k来记录到y轴的距离;
                k1 = x0;flag1 = 1;
            }else{
                k1 = (coordinates[i][1] - y0)* 1.0 / (coordinates[i][0] - x0);

            }
            if(k1 != k0||flag0 != flag1)return false;
        }
        return true;
    }
};

1037有效的回旋镖

解题思路

注意是:不在一条直线上 才返回true;
//其实可以不用 判断是否有重复的点,因为只要 有重复的点,那么这三个点必定在同一条直线上。
题中先判断是否有重复的点,经过筛选后,就没有重复的点了。
如果0,1两点x不等,那么就直接计算k0,如果1,2x相等,那么必定不在一条直线上(因为1,2的y必定不等)
如果0,1两点x相等,那么直接看0,2两点x是否相等,如果不等 ,那么必定 不在一条直线上。return true;反之相等 return false;

代码

class Solution {
public:
    bool isBoomerang(vector<vector<int>>& point) {
        /*
        直接判断是否都在一条直线上就行。
        两点构成一条直线,所以计算任意两条直线的斜率K即可.
        为了避免有重复的点,可以选择计算所有任意两个点的斜率。
        */
        if(point[0][0] == point[1][0]&&point[0][1] == point[1][1]){
            return false;
        }else if(point[0][0] == point[2][0]&&point[0][1] == point[2][1]){
            return false;
        }else if(point[1][0] == point[2][0]&&point[1][1] == point[2][1]){
            return false;
        }
        double k1 = 0;
        double k2 = 0;
        if(point[0][0]-point[1][0]!=0){
            k1 = (point[0][1] - point[1][1])* 1.0/(point[0][0]-point[1][0]);
            if(point[0][0]-point[2][0]!=0){
                k2 = (point[0][1] - point[2][1]) * 1.0/(point[0][0]-point[2][0]);
                if(k1 == k2)return false;
                else return true; 
            }else{
                return true;
            }
        }
            
        else{
            k1 = point[0][0];
            if(point[1][0]-point[2][0]!=0){
                return true;
            }else{
                return false;
            }
        }  
    }
};

88合并两个有序数组

解题思路

因为直接在nums1数组上进行比较会不断使其内的数向后移动,浪费时间。
所以放在第三个数组中,最终再依次赋值回去。
在while循环中只有s1,s2都遍历结束后再退出循环即可。

代码

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        /*
            1.建立两个指针,nums1一定最长,如果时s2遍历完了,那么直接返回即可。
        */
        int sorted[n+m];
        int cur;
        int p1 = 0;int p2 = 0;
        while(p1<m || p2<n){
            if(p1 == m){
                cur = nums2[p2++];
            }else if(p2 == n){
                cur = nums1[p1++];
            }else if(nums1[p1] < nums2[p2]){
                cur = nums1[p1++];
            }else{
                cur = nums2[p2++];
            }
            sorted[p1 + p2 -1] = cur;//每次最多有一个加一(要么p1++,要么p2++)
        }
        for(int i = 0;i!=m + n;i++){
            nums1[i] = sorted[i];
        }
    }
};

912排序树组

解题思路

每次在randomized_partition中挑选一个主元并且会在此函数内调用partition函数进行左右分类。
(要知道,randomized_partition函数调用结束后,只会得到为主元左侧皆小于等于主元,右侧皆大于主元的序列,并没对两侧的序列进行排序)。所以要不断地进入左侧,和右侧进行randomized_partition函数的调用,因为,我们需要再选一个主元,然后再根据其值在左右两侧进行分类。直到,选完某个主元后,其左侧或者右侧都最多只有 1个元素,那么就可以是一个完整的排序完毕的小序列了,再依次返回即可。

代码

class Solution {
public:
    int partition(vector<int>&nums,int l, int r){
        int pivot = nums[r];
        int i = l - 1;//为什么i 要 - 1,为了方便一会循环中的修改。
        //即i始终是小于等于主元的那些数中最右边的那个。
        for(int j = l;j <= r - 1;j++){
            if(nums[j] <= pivot){
                i = i + 1;
                swap(nums[i],nums[j]);
            }
        }
        //最后将主元和大于主元的数中最小的那个进行交换.
        swap(nums[i + 1],nums[r]);
        return i + 1;
    }
    int randomized_partition(vector<int>& nums,int l ,int r){
        int i = rand() % (r - l + 1) + l;//随机选取作为主元。
        swap(nums[r],nums[i]);//将选中的主元放置在数组最末。
        return partition(nums,l,r);
    }
    void randomized_quicksort(vector<int>& nums,int l ,int r){
        if(l < r){
            int pos = randomized_partition(nums,l,r);
            randomized_quicksort(nums,l, pos - 1);
            randomized_quicksort(nums,pos + 1,r);
        }
    }
    vector<int> sortArray(vector<int>& nums) {
        srand((unsigned)time(NULL));//啥意思
        randomized_quicksort(nums,0,(int)nums.size()-1);
        return nums;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值