{"id":4434,"date":"2022-01-21T11:25:29","date_gmt":"2022-01-21T09:25:29","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4434"},"modified":"2022-01-21T11:25:31","modified_gmt":"2022-01-21T09:25:31","slug":"finding-the-second-largest-element-in-a-range","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/","title":{"rendered":"Finding the second largest element in a range"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In recent days, there&#8217;s been a question coming up on twitter: how do you find the second largest element in an array (container)? People are providing different answers. As usual, there are multiple solutions to this problem and they depend on the actual requirements: could this operation have side effect (change the original range) or should it be left untouched? In this post, I will discuss several solutions in C++ to this problem.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Before going forward, I want to add some more requirements:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>if the range is empty, the function must not return any value<\/li><li>if the range has only one element, the function must return this element<\/li><li>if all the range elements have the same value, the function must return this value<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You could argue whether these make sense or not but I will start with these premises.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Scenario 1: the range must not be modified<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s first assume that the range must not be modified by this operation. I would guess that this should be the requirement in most cases when you need to find the second largest element. As someone put it on Twitter:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-twitter wp-block-embed-twitter\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/twitter.com\/Peter_shirley\/status\/1482988275195281408\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There are two possible solutions for this: a user-defined search and using <code>std::max_element<\/code>. Let&#8217;s see them both.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">User-defined search function<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We can write and explicit iteration of the range and compare elements to find the 2nd largest. The algorithm is as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>define two variables to store the 1st and 2nd largest values and initialize them with the first two elements of the range<\/li><li>iterate the range until the end doing the following:<ul><li>if the current element is greater than the largest, then assign 2nd largest to the value of 1st largest, and the 1st largest to the current element<\/li><li>otherwise, if the current element is greater than the 2nd largest then assign its value to the 2nd largest<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This can be implemented as follows using a function template that takes iterators to the first and last elements of a range:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename Iter>\nIter find_2nd_largest_1(Iter begin, Iter end)\n{\n   if (begin == end) return end;\n   if (std::distance(begin, end) == 1) return begin;\n\n   auto max1 = begin++;\n   auto max2 = begin++;\n   if (*max1 &lt; *max2) std::swap(max1, max2);\n\n   for (auto it = begin; it != end; ++it)\n   {\n      if (*it > *max1)\n      {\n         max2 = max1;\n         max1 = it;\n      }\n      else if (*it > *max2 &amp;&amp; *it &lt; *max1)\n      {\n         max2 = it;\n      }\n   }\n\n   return max2;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that the first two checks are meant to ensure the first two requirements defined in the beginning are properly handled.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using std::max_element<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A second alternative is to use the <code>std::max_element<\/code> general purpose algorithm. However, we need to use this twice:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the first call would find the largest element in the range<\/li><li>the second call would require a comparer to help find the largest element that is smaller than the element found with the first call<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Of course, this means there are two passes through the range and this implies a degraded performance as the number of elements increases. But will see about this later. The following is a possible implementation:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename Iter>\nIter find_2nd_largest_2(Iter begin, Iter end)\n{\n   if (begin == end) return end;\n   if (std::distance(begin, end) == 1) return begin;\n\n   auto m = std::max_element(begin, end);\n\n   auto m2 = std::max_element(\n      begin, end, [m](auto const&amp; e1, auto const&amp; e2) { return e2 &lt; *m &amp;&amp; e1 &lt; e2; });\n\n   return m2;\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Scenario 2: the range can be modified<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Assuming you can modify the original range there are additional solutions to the problem using partial sorting algorithms from the standard library. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(As a side note, I&#8217;d like to hear some use cases where modifying the range is OK, but that&#8217;s a side issue for now.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using std::nth_element<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/nth_element\" target=\"_blank\" rel=\"noreferrer noopener\">std::nth_element<\/a> function is a partial sorting algorithm that rearranges elements in a range. It takes two iterators that define the range (begin and last) and a pivot (the nth element) and sorts the range such that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the element pointed by the pivot is changed with the element that would occur in that position if the range was sorted<\/li><li>all the elements before the pivot are changed so they are less or equal to the elements after the new pivot (nth element)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">We can partially sort the range using the 2nd element as the pivot, and using operator <code>><\/code> instead of the default operator <code>&lt;<\/code> for comparison (in other words we would sort descending, not ascending).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the implementation:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename Iter>\nIter find_2nd_largest_3(Iter begin, Iter end)\n{\n   if (begin == end) return end;\n   if (std::distance(begin, end) == 1) return begin;\n\n   std::nth_element(begin, begin + 1, end, std::greater&lt;>());\n\n   return begin + 1;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is even less code than with <code>std::max_element<\/code> although remember, the range is modified.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using std::partial_sort<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/partial_sort\" target=\"_blank\" rel=\"noreferrer noopener\">std::partial_sort<\/a> function is a general purpose algorithm that rearranges elements in a range based on a pivot so that the <code>pivot - first<\/code> smallest elements come first followed by the other elements in an specified order.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Again, the default behavior is to sort using operator <code>&lt;<\/code> so we need to change this and sort using operator <code>><\/code>. We only need to sort the largest two elements of the range, so the pivot would be <code>begin + 2<\/code>. Here is how the implementation would look:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename Iter>\nIter find_2nd_largest_4(Iter begin, Iter end)\n{\n   if (begin == end) return end;\n   if (std::distance(begin, end) == 1) return begin;\n\n   std::partial_sort(begin, begin + 2, end, std::greater&lt;>());\n\n   return begin + 1;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is very similar to the previous implementation. The question is, which is faster? But before answering that, let&#8217;s see if they actually do the right thing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the implementations<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To put these implementations to test, we can write the following simple tests to ensure they always return the expected value:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void basic_tests()\n{\n   std::vector&lt;std::pair&lt;std::optional&lt;int>, std::vector&lt;int>>> data = {\n      {{}, { }},\n      {1, { 1}},\n      {1, { 1, 2}},\n      {1, { 2, 1}},\n      {2, { 2, 3, 1}},\n      {2, { 3, 2, 1}},\n      {1, { 1, 1, 1 }},\n      {1, { 1, 2, 1 }},\n      {1, { 1, 2, 2 }},\n      {4, { 1, 2, 3, 4, 5 }},\n      {5, { 1, 2, 3, 4, 5, 6 }},\n      {4, { 5, 4, 3, 2, 1 }},\n      {5, { 6, 5, 4, 3, 2, 1 }},\n      {8, { 4, 2, 1, 5, 8, 6, 9, 3, 7 }},\n   };\n\n   std::cout &lt;&lt; std::format(\"{:&lt;10} {:&lt;10} {:&lt;10} {:&lt;10} {:&lt;10}\\n\", \n      \"expected\", \"manual\", \"max\", \"nthelem\", \"partsort\");\n\n   for (auto const &amp; [e, v] : data)\n   {\n      auto m1 = find_2nd_largest_1(v.begin(), v.end());\n      auto m2 = find_2nd_largest_2(v.begin(), v.end());\n      auto v3 = v;\n      auto m3 = find_2nd_largest_3(v3.begin(), v3.end());\n      auto v4 = v;\n      auto m4 = find_2nd_largest_4(v4.begin(), v4.end());\n\n      std::cout &lt;&lt; std::format(\"{:&lt;10} {:&lt;10} {:&lt;10} {:&lt;10} {:&lt;10}\\n\",\n         (bool)e ? std::to_string(e.value()) : \"N\/A\",\n         m1 != v.end() ? std::to_string(*m1) : \"N\/A\",\n         m2 != v.end() ? std::to_string(*m2) : \"N\/A\",\n         m3 != v3.end() ? std::to_string(*m3) : \"N\/A\",\n         m4 != v4.end() ? std::to_string(*m4) : \"N\/A\");\n   }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we run this, we get the following output:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">expected   manual     max        nthelem    partsort\nN\/A        N\/A        N\/A        N\/A        N\/A\n1          1          1          1          1\n1          1          1          1          1\n1          1          2 [!]      1          1\n2          2          2          2          2\n2          2          3 [!]      2          2\n1          1          1          1          1\n1          1          1          1          1\n1          1          1          2 [!]      2 [!]\n4          4          4          4          4\n5          5          5          5          5\n4          4          5          4          4\n5          5          6 [!]      5          5\n8          8          8          8          8<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">An exclamation mark here indicates the result is not what was expected. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s first look at <code>std::max_element<\/code>. It got the wrong results for the following test cases:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{ 2, 1}\n{ 3, 2, 1}\n{ 6, 5, 4, 3, 2, 1 }<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We can notice here that the maximum element is always the first. There is a bug on this line:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto m2 = std::max_element(begin, end, [m](auto const&amp; e1, auto const&amp; e2) { return e2 &lt; *m&amp;&amp; e1 &lt; e2; });<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It starts with the first element and compares it against each of the rest and the maximum but it will never find something larger. We need to modify this: when the largest is the first, then continue from the second element:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename Iter>\nIter find_2nd_largest_2(Iter begin, Iter end)\n{\n   if (begin == end) return end;\n   if (std::distance(begin, end) == 1) return begin;\n\n   auto m = std::max_element(begin, end);\n\n   auto m2 = std::max_element(\n      m == begin ? begin + 1 : begin, end, [m](auto const&amp; e1, auto const&amp; e2) { return e2 &lt; *m&amp;&amp; e1 &lt; e2; });\n\n   return m2;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With this change, <code>find_2nd_largest_2<\/code> always returns the expected value.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second problem is related to <code>std::nth_element<\/code> and <code>std::partial_sort<\/code>. They both fail for the range <code>{ 1, 2, 2 }<\/code>. We can see here that the maximum element appears multiple times. There was an implicit assumption that this would not appear more than once. If that&#8217;s not true, then these two solutions do not work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Comparing performance<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The last but not least thing to check is how do they perform against each other. For this, I have written another simple test. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void benchmark()\n{\n   std::cout &lt;&lt; std::format(\"{:>10} {:>10} {:>10} {:>10} {:>10}\\n\",\n      \"size\", \"manual\", \"max\", \"nthelem\", \"partsort\");\n\n   std::vector&lt;size_t> sizes{ 1000, 10000, 100000, 1000000, 10000000 };\n   for (auto size : sizes)\n   {\n      std::vector&lt;int> data;\n      generate(data, size);\n\n      auto d3 = data;\n      auto d4 = data;\n\n      auto t1 = std::chrono::steady_clock::now();\n\n      auto m1 = find_2nd_largest_1(data.begin(), data.end());\n\n      auto t2 = std::chrono::steady_clock::now();\n\n      auto m2 = find_2nd_largest_2(data.begin(), data.end());\n\n      auto t3 = std::chrono::steady_clock::now();\n\n      auto m3 = find_2nd_largest_3(d3.begin(), d3.end());\n\n      auto t4 = std::chrono::steady_clock::now();\n\n      auto m4 = find_2nd_largest_4(d4.begin(), d4.end());\n\n      auto t5 = std::chrono::steady_clock::now();\n\n      if (*m1 == *m2 || *m1 == *m3 || *m1 == *m4) \/\/ this is just to ensure calls are not remove because of optimizations\n      {\n         std::cout &lt;&lt; std::format(\n            \"{:>10} {:>10} {:>10} {:>10} {:>10}\\n\",\n            size,\n            std::chrono::duration_cast&lt;std::chrono::microseconds>(t2 - t1).count(),\n            std::chrono::duration_cast&lt;std::chrono::microseconds>(t3 - t2).count(),\n            std::chrono::duration_cast&lt;std::chrono::microseconds>(t4 - t3).count(),\n            std::chrono::duration_cast&lt;std::chrono::microseconds>(t5 - t4).count()\n         );\n      }\n   }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run with optimizations enabled (a release build) I get the following numbers (of course, these vary slightly with each run):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">      size     manual        max    nthelem   partsort\n      1000          1          3         11          1\n     10000         11         28        112          6\n    100000        104        293       1306        107\n   1000000       4044       8083      10364       4020\n  10000000      25980      34281      66386       5834<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There are several thing to notice here:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the implementation using two calls to <code>std::max_element<\/code> is always less performant than the manual search (about twice as much time to find the 2nd largest)<\/li><li>the implementation using the <code>std::nth_element<\/code> is the least performant of them all<\/li><li>the implementation using <code>std::partial_sort<\/code> is comparable to the manual search and several times faster when there are 10 million elements in the range<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The reason <code>std::partial_sort<\/code> is much faster than <code>std::nth_element<\/code> is that it does much fewer swaps. This is demonstrated in a cppcon talk by Marshall Clow: <a href=\"https:\/\/www.youtube.com\/watch?v=9Tx97HeGnUQ\" target=\"_blank\" rel=\"noreferrer noopener\">Down the Rabbit Hole: An Exploration of Stack Overflow Questions<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<span class=\"embed-youtube\" style=\"text-align:center; display: block;\"><iframe loading=\"lazy\" class=\"youtube-player\" width=\"1200\" height=\"675\" src=\"https:\/\/www.youtube.com\/embed\/9Tx97HeGnUQ?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent\" allowfullscreen=\"true\" style=\"border:0;\" sandbox=\"allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox\"><\/iframe><\/span>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problems usually have multiple solutions and finding the 2nd largest element in a range is no different. In my opinion, modifying the range is rarely an option, so, usually, you&#8217;d have to chose between the first two implementations. The manual search is faster but if you only have a small number of elements using <code>std::max_element<\/code> twice should not represent a performance problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In recent days, there&#8217;s been a question coming up on twitter: how do you find the second largest element in an array (container)? People are providing different answers. As usual, there are multiple solutions to this problem and they depend on the actual requirements: could this operation have side effect (change the original range) or should it be left untouched? In this post, I will discuss several solutions in C++ to this problem.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451],"class_list":["post-4434","post","type-post","status-publish","format-standard","hentry","category-c","tag-c"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Explore different solutions for finding the second largest element in a range in C++\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Finding the second largest element in a range\" \/>\n\t\t<meta property=\"og:description\" content=\"Explore different solutions for finding the second largest element in a range in C++\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2022-01-21T09:25:29+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2022-01-21T09:25:31+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Finding the second largest element in a range\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Explore different solutions for finding the second largest element in a range in C++\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#article\",\"name\":\"Finding the second largest element in a range\",\"headline\":\"Finding the second largest element in a range\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2022-01-21T11:25:29+02:00\",\"dateModified\":\"2022-01-21T11:25:31+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":1,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#webpage\"},\"articleSection\":\"C++, C++\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#listItem\",\"name\":\"Finding the second largest element in a range\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#listItem\",\"position\":5,\"name\":\"Finding the second largest element in a range\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/\",\"name\":\"Finding the second largest element in a range\",\"description\":\"Explore different solutions for finding the second largest element in a range in C++\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/21\\\/finding-the-second-largest-element-in-a-range\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2022-01-21T11:25:29+02:00\",\"dateModified\":\"2022-01-21T11:25:31+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Finding the second largest element in a range","description":"Explore different solutions for finding the second largest element in a range in C++","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/","robots":"max-image-preview:large","keywords":"c++","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#article","name":"Finding the second largest element in a range","headline":"Finding the second largest element in a range","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2022-01-21T11:25:29+02:00","dateModified":"2022-01-21T11:25:31+02:00","inLanguage":"en-US","commentCount":1,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#webpage"},"articleSection":"C++, C++"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#listItem","name":"Finding the second largest element in a range"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#listItem","position":5,"name":"Finding the second largest element in a range","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/","name":"Finding the second largest element in a range","description":"Explore different solutions for finding the second largest element in a range in C++","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2022-01-21T11:25:29+02:00","dateModified":"2022-01-21T11:25:31+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Finding the second largest element in a range","og:description":"Explore different solutions for finding the second largest element in a range in C++","og:url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/21\/finding-the-second-largest-element-in-a-range\/","article:published_time":"2022-01-21T09:25:29+00:00","article:modified_time":"2022-01-21T09:25:31+00:00","twitter:card":"summary","twitter:title":"Finding the second largest element in a range","twitter:description":"Explore different solutions for finding the second largest element in a range in C++"},"aioseo_meta_data":{"post_id":"4434","title":null,"description":"Explore different solutions for finding the second largest element in a range in C++","keywords":[],"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-6369651302d0c","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2022-01-21 06:56:13","updated":"2025-12-12 07:57:11","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":1,"uagb_excerpt":"In recent days, there's been a question coming up on twitter: how do you find the second largest element in an array (container)? People are providing different answers. As usual, there are multiple solutions to this problem and they depend on the actual requirements: could this operation have side effect (change the original range) or&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]}},"comment_count":"1","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on January 21, 2022","modified":"Updated on January 21, 2022"},"absolute_dates_time":{"created":"Posted on January 21, 2022 11:25 am","modified":"Updated on January 21, 2022 11:25 am"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-19w","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4434","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4434"}],"version-history":[{"count":7,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4434\/revisions"}],"predecessor-version":[{"id":4441,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4434\/revisions\/4441"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}