【LeetCode 976】Largest Perimeter Triangle 最大三角形周长(C++&Python)——学习使用C++的sort()和Python中的list.sort()

LeetCode 976. Largest Perimeter Triangle EASY

一、题目

Given an array A of positive lengths, return the largest perimeter of a triangle with non-zero area, formed from 3 of these lengths.

If it is impossible to form any triangle of non-zero area, return 0.

Example 1:

Input: [2,1,2]
Output: 5

Example 2:

Input: [1,2,1]
Output: 0

Example 3:

Input: [3,2,3,4]
Output: 10

Example 4:

Input: [3,6,2,3]
Output: 8

Note:

  1. 3 <= A.length <= 10000
  2. 1 <= A[i] <= 10^6 

二、分析

1. 题意 

给定一串数,要求从中找出能够组成三角形 且使得三角形周长最大的三个数,return三角形最大周长;如果给定数中不能满足此要求,return 0。

此题的参数为容器vector<int>A,关于Vector容器:

向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组

2. 思路 

此题中可以将A理解成一个数组作为参数。从数学角度,此题要找的三个数字需要符合以下条件:

  1. 三个数中两个较小数之和大于最大数
  2. 三个数在数列中相对最大,相对最大≠最大,因为最大的三个数很可能无法组成三角形

此处先解决2,即可以用排序的方法,将数列从小到大/从大到小排列。而后解决1,有条件地寻找三个相对较大的数。

三、题解(C++ & Python)

1. C++

在答案中,用到了sort()函数和reverse()函数,具体用法见第四部分。

//此答案用时120 ms,消耗内存:21.1 MB,并不算是十分理想,但是解决了问题

class Solution {
public:
    int largestPerimeter(vector<int>& A) {
        //assert if less than 2 elements
        if (A.size() < 3) {
            return 0;
        }
        sort(A.begin(), A.end());
        reverse(A.begin(), A.end());
        //assert if 3rd element is zero, that would not form a triangle
        if (A[2] == 0) {
            return 0;
        }
        for (int i = 0; i < size(A) - 2; i++) {
            if (A[i] < (A[i + 1] + A[i + 2])) {
                return A[i] + A[i + 1] + A[i + 2];
                break;
            }
        }
        return 0;
    }
};

2. Python

此答案中使用了list.sort()方法,具体用法见第五部分。

#执行用时:232 ms,内存消耗:14.8 MB
class Solution:
    def largestPerimeter(self, A: List[int]) -> int:
        A.sort(reverse=True)
        if len(A)<3:
            return 0
        if A[2]==0:
            return 0
        for i in range(len(A)-2):
            if A[i]<(A[i+1]+A[i+2]):
                return A[i]+A[i+1]+A[i+2]
                break
        return 0

四、C++中的sort()函数和reverse()函数

1. 头文件 

用之前记得引用头文件algorithm:

#include<algorithm>

2.  默认用法(两个参数)

sort函数的参数依次有三个:首元素地址、尾元素的下一个地址、比较函数。当比较int或者double时,结果为升序排列;当比较char时,结果为字典序排列:

//default
template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);

注意此处的排序的范围是[first, last),即并不包括last参数本身,所以在实际使用时,我们更喜欢写成sort(首元素地址,尾元素的下一个地址),即:

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator next_to_last);

int型数组利用sort()实现升序排列:

//int array example
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int array[4]={1, 5, 2, -4};
    sort(array.begin(), array.end());    
    //begin()和end()分别指向array的第一个元素和最后一个元素的下一个位置
    for(int i=0; i<size(array); i++){
        cout<<array[i]<<endl;
        }
    return 0;
}

char型数组利用sort()实现字典序排列:

//char array example
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    char array[4]={'T', 'A', 'Z', 'a'};
    sort(array.begin(), array.end());    
    //begin()和end()分别指向array的第一个元素和最后一个元素的下一个位置
    for(int i=0; i<size(array); i++){
        cout<<array[i]<<endl;
        }
    return 0;
}

3. 第三个参数comp

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

根据C++ Reference,此处的comp解释为:

Binary function that accepts two elements in the range as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.

简言之,第三个参数comp实际上是一个函数(function),它接收两个参数,返回一个可以转换成bool型的值。在strict weak ordering的规则下,如果判定第一个参数和第二个参数相比 较小,则返回True。

strict weak ordering是一个更复杂的概念,在此不做赘述,可以参考walkerlala的文章:C++: Strict Weak Ordering

也就是说,我们可以自定义一个函数comp,自主规定排序的规则。比如我们可以自定义int型数组的降序排列:

//int array sorting with comp function
#include<iostream>
#include<algorithm>
using namespace std;
//定义降序排列
bool cmp(int a, int b){
    return a>b;
}

int main(){
    int array[4]={1, 5, 2, -4};
    sort(array.begin(), array.end(), cmp);    
    for(int i=0; i<size(array); i++){
        cout<<array[i]<<endl;
        }
    return 0;
}

甚至还可以对结构体数组定义比较规则,从而进行比较:

//struct array sorting with comp function
#include<iostream>
#include<algorithm>
using namespace std;
//定义学生类,有整形变量num(学号)和grade(成绩)
strct student{
    int num;
    int grade;
}
//定义排列规则
bool cmp(student a, student b){
    //如果成绩不相同,按成绩降序排列
    if(a.grade!=b.grade)
        return a.grade>b.grade;
    //如果成绩相同,按学号升序排列
    else
        retrun a.num<b.num;
}
int main(){
    student[0].grade=98;
    student[0].num=01;

    student[1].grade=96;
    student[1].num=02;

    student[2].grade=92;
    student[2].num=03;

    student[3].grade=92;
    student[3].num=04;
    
    sort(student.begin(), student.end(), cmp);
}

4. reverse()函数

reverse()会将区间[beg,end)内的元素全部逆序。

五、Python中的list.sort()方法

Python中的list.sort()方法使用起来比较简单,它含有两个参数,使用方法为:

list.sort( key=None, reverse=False)

参数key是用来进行比较的元素,参数reverse是排序规则,reverse = True时降序, reverse = False为升序,是默认值。

六、Reference

C++ Reference: http://www.cplusplus.com/reference/algorithm/sort/

strict weak ordering:https://www.cnblogs.com/walkerlala/p/5561339.html

Python3 List sort()方法:https://www.runoob.com/python3/python3-att-list-sort.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值