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:
3 <= A.length <= 10000
1 <= A[i] <= 10^6
二、分析
1. 题意
给定一串数,要求从中找出能够组成三角形 且使得三角形周长最大的三个数,return三角形最大周长;如果给定数中不能满足此要求,return 0。
此题的参数为容器vector<int>A,关于Vector容器:
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
2. 思路
此题中可以将A理解成一个数组作为参数。从数学角度,此题要找的三个数字需要符合以下条件:
- 三个数中两个较小数之和大于最大数
- 三个数在数列中相对最大,相对最大≠最大,因为最大的三个数很可能无法组成三角形
此处先解决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