STL: prev,upper_bound,binary_search
还是来自大神的题解:https://github.com/soulmachine/leetcode
class Solution { public: vector<vector<int>> threeSum(vector<int>& num) { vector<vector<int>> result; if (num.size() < 3) return result; sort(num.begin(), num.end()); const int target = 0; auto last = num.end(); for (auto a = num.begin(); a < prev(last, 2); a = upper_bound(a, prev(last, 2), *a)) { for (auto b = next(a); b < prev(last); b = upper_bound(b, prev(last), *b)) { const int c = target - *a - *b; if (binary_search(next(b), last, c)) result.push_back(vector<int> { *a, *b, c }); } } return result; } };
又碰到了不会的stl的用法,如下:
prev:
template <class BidirectionalIterator> BidirectionalIterator prev (BidirectionalIterator it, typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
Returns an iterator pointing to the element that it would be pointing to if advanced -n
positions.
If it is a random-access iterator, the function uses just once operator+
or operator-
. Otherwise, the function uses repeatedly the increase or decrease operator (operator++
or operator--
) on the copied iterator until n elements have been advanced.
所以上面的a<prev(last,2)就是a<倒数第二个元素的位置。
upper_bound:
default (1) |
template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val); |
---|---|
custom (2) |
template <class ForwardIterator, class T, class Compare> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); |
Returns an iterator pointing to the first element in the range [first,last)
which compares greater than val.
The elements are compared using operator<
for the first version, and comp for the second. The elements in the range shall already be sorted according to this same criterion (operator<
or comp), or at least partitioned with respect to val.
The function optimizes the number of comparisons performed by comparing non-consecutive elements of the sorted range, which is specially efficient for random-access iterators.
If no element in the range compares greater than val, the function returns last.
返回在range里面第一个比val大的元素。因为数组是排好序的,所以这里upper_bound主要起到了去重的作用。
有个lower_bound和这个类似,不过lower_bound是 does not compare less than val。 也就是只要大于等于就可以了。
binary_search:
default (1) |
template <class ForwardIterator, class T> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); |
---|---|
custom (2) |
template <class ForwardIterator, class T, class Compare> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); |
Returns true
if any element in the range [first,last)
is equivalent to val, and false
otherwise.
The elements are compared using operator<
for the first version, and comp for the second. Two elements, a and b are considered equivalent if (!(a<b) && !(b<a))
or if (!comp(a,b) && !comp(b,a))
.
如果在范围里存在这么一个val,那么返回true,否则是false。
所以上面的代码里有了a,b,那么0-a-b得到c的值,那么在(b,last)之间二分查找下是不是存在这么一个等于c的元素,有的话就得到了一个a,b,c的组合,加入res中。
感慨一下,用好了STL还真是方便,我记得当时自己写的时候因为自己实现了二分查找所以整个代码看起来就没这么简洁。