<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>西瓜田 &#187; 水题</title>
	<atom:link href="http://blog.thpiano.com/?feed=rss2&#038;tag=%E6%B0%B4%E9%A2%98" rel="self" type="application/rss+xml" />
	<link>http://blog.thpiano.com</link>
	<description>无复洛城东</description>
	<lastBuildDate>Tue, 19 Jan 2021 03:54:37 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>寻找最大的非重复数</title>
		<link>http://blog.thpiano.com/?p=527</link>
		<comments>http://blog.thpiano.com/?p=527#comments</comments>
		<pubDate>Sun, 15 Apr 2012 07:50:50 +0000</pubDate>
		<dc:creator>suika</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[华为]]></category>
		<category><![CDATA[水题]]></category>

		<guid isPermaLink="false">http://blog.thpiano.com/?p=527</guid>
		<description><![CDATA[好像好久都没在编程栏目下投新稿了（ 那就来篇水点的，顺便测试下代码高亮插件 报了华为编程大赛，找了去年的题，看到了这道： 如果一个数字十进制表达时，不存在连续两位相同，则称之为“不重复数”。 例如，105、1234和12121都是“不重复数”，而11、100和1225不是。 给定一个正整数A，返回大于A的最小“不重复数”。A小于100000 初见一看，从所给之数开始依次加一，判断新的数是否是重复数就行了，可谓是最笨而又保险的做法 很快写完后，恰好有友人过来一同讨论，是否有更优的算法呢？ &#160; 先从这个每步+1着手，诸如122421这样的数，千位和万位重复，再从个位加真是太累了；于是改成从高位向低位遍历，遇到重复的邻近位就把低位+1，至少效率会比+1好多了； 对122421采用这种做法，会+1000变成123421，看上去的确是不重复了，但却丢失了最小性（最小的应该是123010） 因此，在修改重复位之后，还需要把低位重置，重置成0、1相邻的序列，就能弥补最小性了 例如122121，先+1000变为123121，再从123后面填入序列，得到123010； 例如120014，先+100变为120114，再从1201后面填入序列，得到120101 &#160; 在这种做法下，循环数量可谓是大大减少了，很多情况下更是一步到位；但是依然没有摆脱“自增修改-&#62;判断是否为重复数”的循环试探法 要得到一步到位的稳定法，还需考虑进位的情况： 例如1219922，在遍历到9并+100后，变为1220022，会对已遍历过的高位引入新的重复；此时再将遍历位回退2位重新遍历，即能解决进位带来的不稳定情况 &#160; 总结一下，最终一步到位的算法步骤为： 1.将原数+1得到目标数字 2.对目标数字从高位向低位遍历，若未发现邻近重复数字，则转入步骤4；否则将2个重复数字中的低位数字+1，并记录重复处之后的低位位数 3.遍历位置回退2，重复步骤2 4.若记录了重复处之后的低位位数，则将这些低位用0、1相间的序列进行填充；返回修改后的目标数字 &#160; 顺便附上输入数据为整形时的代码（c++字符串的代码有点长就不贴了）： 12345678910111213141516unsigned int GetNotRepeatNum&#40;unsigned int lValue&#41;&#123; &#160; &#160; int temp, aim = lValue + 1; &#160; &#160; int divide = pow&#40;10.0f, int&#40;log10&#40;double&#40;aim&#41;&#41;&#41; - 1&#41;; &#160; &#160; while &#40;divide &#62;= 1&#41;&#123; [...]]]></description>
			<content:encoded><![CDATA[<p>好像好久都没在编程栏目下投新稿了（</p>
<p>那就来篇水点的，顺便测试下代码高亮插件</p>
<p><span id="more-527"></span></p>
<p>报了华为编程大赛，找了去年的题，看到了这道：</p>
<pre>如果一个数字十进制表达时，不存在连续两位相同，则称之为“不重复数”。
例如，105、1234和12121都是“不重复数”，而11、100和1225不是。
给定一个正整数A，返回大于A的最小“不重复数”。A小于100000</pre>
<p>初见一看，从所给之数开始依次加一，判断新的数是否是重复数就行了，可谓是最笨而又保险的做法</p>
<p>很快写完后，恰好有友人过来一同讨论，是否有更优的算法呢？</p>
<p>&nbsp;</p>
<p>先从这个每步+1着手，诸如122421这样的数，千位和万位重复，再从个位加真是太累了；于是改成从高位向低位遍历，遇到重复的邻近位就把低位+1，至少效率会比+1好多了；</p>
<p>对122421采用这种做法，会+1000变成123421，看上去的确是不重复了，但却丢失了最小性（最小的应该是123010）</p>
<p>因此，在修改重复位之后，还需要把低位重置，重置成0、1相邻的序列，就能弥补最小性了</p>
<p>例如122121，先+1000变为123121，再从123后面填入序列，得到123010；</p>
<p>例如120014，先+100变为120114，再从1201后面填入序列，得到120101</p>
<p>&nbsp;</p>
<p>在这种做法下，循环数量可谓是大大减少了，很多情况下更是一步到位；但是依然没有摆脱“自增修改-&gt;判断是否为重复数”的循环试探法</p>
<p>要得到一步到位的稳定法，还需考虑进位的情况：</p>
<p>例如1219922，在遍历到9并+100后，变为1220022，会对已遍历过的高位引入新的重复；此时再将遍历位回退2位重新遍历，即能解决进位带来的不稳定情况</p>
<p>&nbsp;</p>
<p>总结一下，最终一步到位的算法步骤为：</p>
<p>1.将原数+1得到目标数字</p>
<p>2.对目标数字从高位向低位遍历，若未发现邻近重复数字，则转入步骤4；否则将2个重复数字中的低位数字+1，并记录重复处之后的低位位数</p>
<p>3.遍历位置回退2，重复步骤2</p>
<p>4.若记录了重复处之后的低位位数，则将这些低位用0、1相间的序列进行填充；返回修改后的目标数字</p>
<p>&nbsp;</p>
<p>顺便附上输入数据为整形时的代码（c++字符串的代码有点长就不贴了）：</p>
<div class="codecolorer-container cpp geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span> GetNotRepeatNum<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span> lValue<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">int</span> temp, aim <span style="color: #000080;">=</span> lValue <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">int</span> divide <span style="color: #000080;">=</span> <span style="color: #0000dd;">pow</span><span style="color: #008000;">&#40;</span><span style="color:#800080;">10.0f</span>, <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">log10</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">double</span><span style="color: #008000;">&#40;</span>aim<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>divide <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; temp <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>aim <span style="color: #000040;">/</span> divide<span style="color: #008000;">&#41;</span> <span style="color: #000040;">%</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>temp <span style="color: #000080;">==</span> <span style="color: #008000;">&#40;</span>aim <span style="color: #000040;">/</span> <span style="color: #008000;">&#40;</span>divide <span style="color: #000040;">*</span> <span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">%</span> <span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; aim <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>aim <span style="color: #000040;">/</span> divide <span style="color: #000040;">+</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">*</span> divide<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>temp <span style="color: #000080;">==</span> <span style="color: #0000dd;">9</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; divide <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">100</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><span style="color: #0000ff;">else</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; divide <span style="color: #000040;">/</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> aim<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>最后发现自己实在是太罗嗦了，其实本篇就是一道可以用一句话来概括的水题，“高位到低位扫描，遇到相邻位相同，低位+1，低位后面的全置为0；重复上述直至十位与个位不同”，当然也可以用三个字，“构造法”</p>
<p>最近一段时间也是老夫聊发少年狂，刷了些oj，弥补以前的遗憾；不过也只能从实效性下手，无暇追求排名与AC数了。新手上道，挫折无限，还需多多修炼</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thpiano.com/?feed=rss2&#038;p=527</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
