﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-everyday-文章分类-算法</title><link>http://www.cppblog.com/everyday/category/20590.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 02 Jul 2013 02:45:40 GMT</lastBuildDate><pubDate>Tue, 02 Jul 2013 02:45:40 GMT</pubDate><ttl>60</ttl><item><title>最多连续数的子集</title><link>http://www.cppblog.com/everyday/articles/201439.html</link><dc:creator>everyday</dc:creator><author>everyday</author><pubDate>Mon, 01 Jul 2013 14:05:00 GMT</pubDate><guid>http://www.cppblog.com/everyday/articles/201439.html</guid><wfw:comment>http://www.cppblog.com/everyday/comments/201439.html</wfw:comment><comments>http://www.cppblog.com/everyday/articles/201439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/everyday/comments/commentRss/201439.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/everyday/services/trackbacks/201439.html</trackback:ping><description><![CDATA[微博上<a href="http://weibo.com/lirenchen">@陈利人</a>会不定时的发一些程序员的面试题，觉得挺有意思，有时会去写代码做一下。最近他开了个微信公众号：待字闺中 (id: daiziguizhongren)，推送这些面试题目和网友的一些好的解答。看到他出的面试题目是促使我开这个博客的另一个重要原因。:)<br />
<br />
本文正是关于他出的题目：给一个整数数组，找到其中包含最多连续数的自己，比如给：15，7，12，6，14，13，9，11，则返回5:[11,12,13,14,15]。最简单的方法是sort然后scan一遍，但是要O(nlgn)。有什么O(n)的方法吗？<br />
<br />
跟他确认了下，对空间复杂度有没有什么要求，能不能用map这样的辅助数据结构，他说没有限制。<br />
<br />
我的想法就是，用一个map&lt;int, int&gt;，它的key是一个起始的数字，value是这个起始数字起连续的个数。这样这个数组遍历一遍下来，只要map维护好了，自然就能得到最长的连续子串了，并且算法复杂度应该是O(n)。（不考虑map函数实现的复杂度）<br />
前面说了维护好map就可以了，那么怎么来维护这个map呢？<br />
<ol style="list-style-type: decimal;">
     <li>取出当前的整数，在map里看一下是否已经存在，若存在则直接取下一个，不存在转2 (为什么要看是否已经存在，因为题目没有说不会有重复的数字。)</li>
     <li>查看下map里面当前数字的前一个是否存在，如果存在，当前的最长长度就是前一个最长长度+1</li>
     <li>查看下map里面当前数字的后一个是否存在，如果存在，那么就将以下一个数字开始的子串的最后一个更新下，因为本来没有连上的2个子串，因为当前数字的出现连起来了
     </li>
     <li>接着再看下前面数字是否存在，如果存在，就更新以这个数字结尾的子串的第一个数字的连续子串长度，原因同上</li>
</ol>
算法就是如上所示了，我们拿例子演练一遍<br />
1) &nbsp; 首先给定15，这个时候map里面没有15也没有14和16，那么这个执行完了之后map是map[15] = 1;<br />
2) &nbsp; 然后遇到7，同上，也没有6，7和8，所以执行玩了之后变成map[7]=1, map[15]=1;<br />
3) &nbsp; 12同上，map[7]=1, map[12]=1, map[15]=1;<br />
4) &nbsp; 接下来是6，6就不一样了，因为7存在的，所以执行上面第3步之后，map[6]=2,map[7]=2,map[12]=1,map[15]=1;<br />
5) &nbsp; 14的情况跟6一样，结果是map[6]=2,map[7]=2,map[12]=1,map[14]=2,map[15]=2;<br />
6) &nbsp; 13的情况相对复杂一些，因为12和14都存在了 ，所以它会执行以上1，2，3，4的所有4步：首先12存在，所以13的最长子串是2，14存在，所以会更新到14起始的最后一个数字的最长长度，这里就是15的长度=它自己的加上13的长度，也就是4，同时我们把13的长度也改成4，最后因为12存在，我们要更新以12结尾的连续子串的开始处，本例中就是12自己，12对应更新成4<br />
7) &nbsp; 最后是11，11的前面一个数字不存在，后一个数字存在，也就是要执行以上1，3，第3步结束的时候已经是11和15都更新成5了。最后的结果也就是5，并且是从11起始的。<br />
<br />
下面上代码：<br />
&nbsp;<span style="font-size: 13px; color: #008080;">
1</span><span style="background-color: #eeeeee; font-size: 13px;">&nbsp;</span><span style="font-size: 13px; color: #0000ff;">int</span><span style="background-color: #eeeeee; font-size: 13px;">&nbsp;find_longest_consecutive_items(</span><span style="font-size: 13px; color: #0000ff;">int</span><span style="background-color: #eeeeee; font-size: 13px;">&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px;">*</span><span style="background-color: #eeeeee; font-size: 13px;">list,&nbsp;</span><span style="font-size: 13px; color: #0000ff;">int</span><span style="background-color: #eeeeee; font-size: 13px;">&nbsp;size)&nbsp;{</span>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map&lt;<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>&gt;&nbsp;mapping;<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;max&nbsp;=&nbsp;0;<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;The&nbsp;start&nbsp;point&nbsp;for&nbsp;the&nbsp;longest&nbsp;chain</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;start&nbsp;=&nbsp;0;<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i=0;&nbsp;i&lt;size;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(mapping.find(list[i])&nbsp;==&nbsp;mapping.end())&nbsp;{<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;cur&nbsp;=&nbsp;list[i];<br />
<span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Set&nbsp;current&nbsp;position&nbsp;as&nbsp;the&nbsp;start&nbsp;point&nbsp;for&nbsp;this&nbsp;potential&nbsp;longest&nbsp;chain</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;cur_start&nbsp;=&nbsp;cur;<br />
<span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mapping.insert(make_pair(cur,&nbsp;1));<br />
<span style="color: #008080; ">13</span>&nbsp;<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map&lt;<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>&gt;::iterator&nbsp;prev&nbsp;=&nbsp;mapping.find(cur&nbsp;-&nbsp;1);<br />
<span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map&lt;<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>&gt;::iterator&nbsp;next&nbsp;=&nbsp;mapping.find(cur&nbsp;+&nbsp;1);<br />
<span style="color: #008080; ">16</span>&nbsp;<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(prev&nbsp;!=&nbsp;mapping.end())&nbsp;{<br />
<span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;If&nbsp;previous&nbsp;number&nbsp;exists,&nbsp;increase&nbsp;current&nbsp;consecutive&nbsp;count</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mapping[cur]&nbsp;=&nbsp;prev-&gt;second&nbsp;+&nbsp;1;<br />
<span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">21</span>&nbsp;<br />
<span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(next&nbsp;!=&nbsp;mapping.end())&nbsp;{<br />
<span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Update&nbsp;the&nbsp;last&nbsp;one&nbsp;in&nbsp;the&nbsp;chain&nbsp;with&nbsp;the&nbsp;consecutive&nbsp;count&nbsp;from&nbsp;the&nbsp;one&nbsp;before&nbsp;current&nbsp;position</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;last&nbsp;=&nbsp;next-&gt;first&nbsp;+&nbsp;next-&gt;second&nbsp;-&nbsp;1;<br />
<span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mapping[last]&nbsp;=&nbsp;mapping[cur]&nbsp;=&nbsp;mapping[cur]&nbsp;+&nbsp;mapping[last];<br />
<span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">27</span>&nbsp;<br />
<span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(prev&nbsp;!=&nbsp;mapping.end())&nbsp;{<br />
<span style="color: #008080; ">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Update&nbsp;the&nbsp;first&nbsp;one&nbsp;in&nbsp;the&nbsp;chain&nbsp;with&nbsp;the&nbsp;consecutive&nbsp;count&nbsp;from&nbsp;the&nbsp;one&nbsp;after&nbsp;current&nbsp;position</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;first&nbsp;=&nbsp;prev-&gt;first&nbsp;-&nbsp;prev-&gt;second&nbsp;+&nbsp;1;<br />
<span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mapping[first]&nbsp;=&nbsp;mapping[cur];<br />
<span style="color: #008080; ">32</span>&nbsp;<br />
<span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Use&nbsp;the&nbsp;first&nbsp;one&nbsp;as&nbsp;the&nbsp;start&nbsp;point&nbsp;for&nbsp;the&nbsp;whole&nbsp;chain</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur_start&nbsp;=&nbsp;first;<br />
<span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">36</span>&nbsp;<br />
<span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(mapping[cur_start]&nbsp;&gt;&nbsp;max)&nbsp;{<br />
<span style="color: #008080; ">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;=&nbsp;cur_start;<br />
<span style="color: #008080; ">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max&nbsp;=&nbsp;mapping[cur_start];<br />
<span style="color: #008080; ">40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">43</span>&nbsp;<br />
<span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"Longest&nbsp;consecutive&nbsp;items:";<br />
<span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i=0;&nbsp;i&lt;max;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"&nbsp;"&nbsp;&lt;&lt;&nbsp;start&nbsp;+&nbsp;i;<br />
<span style="color: #008080; ">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;endl;<br />
<span style="color: #008080; ">49</span>&nbsp;<br />
<span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;max;<br />
<span style="color: #008080; ">51</span>&nbsp;}<br /><br /><a href="https://interview.codeplex.com/SourceControl/latest#get_longest_consecutive.cpp">完整代码</a></div><img src ="http://www.cppblog.com/everyday/aggbug/201439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/everyday/" target="_blank">everyday</a> 2013-07-01 22:05 <a href="http://www.cppblog.com/everyday/articles/201439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>