找回密码
 立即注册
首页 业界区 业界 返回不重复数的实现 另类实现方式

返回不重复数的实现 另类实现方式

岑韬哎 2025-5-29 14:52:34
原题目请参考: http://www.cnblogs.com/lovexyz123/archive/2009/09/04/1560166.html 
  题目

  如果一个数字十进制表达时,不存在连续两位相同,则称之为“不重复数”。例如,105、164和198都是“不重复数”,而11、100和122不是。
  下面用一个long类型( long类型数字A),实现返回大于A的最小“不重复数”。
  解题思路

  没有详细的统计过大家的解法(很多都在回复内贴的代码)。但感觉大家的问题主要集中在计算大数的效率上。提供一种“经验”算法供大家参考。
  题目按照我的理解,大致为输入99,返回101。输入199,返回201这类的。
  按照人类的(其实就是我的。。哈哈)解题方式,算法分析如下:
  1. 9为特殊字符
  如果这串数字的某一位和其上一位均为9,则需要返回类似“101”这样的数值。
  2. 首位和次位(左起第二位)均为9为特殊情况
  在这种情况下,需进位(增加数字一位)。
  3. 解决连续两位重复的方式为将低位数字+1(9已经当作特殊情况处理,这种情况下不可能为9)。之所以加低位是因为需要返回最小的。
  4. 任何一个数字提升(+1)后,其所有次位(例如1881111中的188变为189,所有次位为1111)都变得不重要。根据“经验”可得知,最小数为所有前位(189)加上(0101)。其中“0101”为固定不重复最小值,其长度与数字所有次位的长度相同,以0开头,用1间隔(依据“不重复数”条件分析而来)。
  5. 由于可能在“99”处理后造成前一位与前两位重复(例如12199变为12201,造成了新的重复),在处理完成后重新调用函数自身进行二次处理。中断条件为结果字串中未发现重复的两位(即“不重复数”)。
  如果按照此思路进行解题运算,大多数情况下算法复杂度只为O(n) (我其实不会算算法复杂度,高手可以提示一下这种算法的复杂度该如何计算。只是要表达和长度相关的意思)
  代码全文

         
  1.    1: using System;
复制代码
  
  1.    2: using System.Collections.Generic;
复制代码
  
  1.    3: using System.Linq;
复制代码
  
  1.    4: using System.Text;
复制代码
  
  1.    5: using System.Text.RegularExpressions;
复制代码
  
  1.    6: using System.Collections.ObjectModel;
复制代码
  
  1.    7: 
复制代码
  
  1.    8: namespace SubStringFrequency
复制代码
  
  1.    9: {
复制代码
  
  1.   10:     class Program
复制代码
  
  1.   11:     {
复制代码
  
  1.   12:         static void Main(string[] args)
复制代码
  
  1.   13:         {
复制代码
  
  1.   14:             var consoleInput = Console.ReadLine();
复制代码
  
  1.   15:             long baseNumber = long.Parse(consoleInput);
复制代码
  
  1.   16: 
复制代码
  
  1.   17:             Console.WriteLine(getAvaliableNum(baseNumber));
复制代码
  
  1.   18:         }
复制代码
  
  1.   19: 
复制代码
  
  1.   20:         private static string getAvaliableNum(long consoleInput)
复制代码
  
  1.   21:         {
复制代码
  
  1.   22:             if (consoleInput < 10) //single number
复制代码
  
  1.   23:             {
复制代码
  
  1.   24:                 return consoleInput.ToString();
复制代码
  
  1.   25:             }
复制代码
  
  1.   26: 
复制代码
  
  1.   27:             string temp = consoleInput.ToString();
复制代码
  
  1.   28:             var reach = 0;
复制代码
  
  1.   29:             StringBuilder result = new StringBuilder();
复制代码
  
  1.   30:             for (int i = 1; i < temp.Length; i++)
复制代码
  
  1.   31:             {
复制代码
  
  1.   32:                 var currentNum = temp[i];
复制代码
  
  1.   33:                 var nextNum = temp[i - 1];
复制代码
  
  1.   34:                 if (currentNum == nextNum)
复制代码
  
  1.   35:                 {
复制代码
  
  1.   36:                     reach += 1;
复制代码
  
  1.   37:                     if (currentNum == '9')
复制代码
  
  1.   38:                     {
复制代码
  
  1.   39:                         if (i == 1)
复制代码
  
  1.   40:                         {
复制代码
  
  1.   41:                             result.Append('1');
复制代码
  
  1.   42:                             result.Append(getMimimumUniqueNumByLength(temp.Length));
复制代码
  
  1.   43:                             break;
复制代码
  
  1.   44:                         }
复制代码
  
  1.   45:                         else
复制代码
  
  1.   46:                         {
复制代码
  
  1.   47:                             var hiNumber = int.Parse(result[result.Length - 1].ToString()) + 1;
复制代码
  
  1.   48:                             result.Remove(result.Length - 1, 1);
复制代码
  
  1.   49:                             result.Append(hiNumber);
复制代码
  
  1.   50:                             result.Append(getMimimumUniqueNumByLength(temp.Length - i + 1));
复制代码
  
  1.   51:                             break;
复制代码
  
  1.   52:                         }
复制代码
  
  1.   53:                     }
复制代码
  
  1.   54:                     else
复制代码
  
  1.   55:                     {
复制代码
  
  1.   56:                         result.Append(nextNum);
复制代码
  
  1.   57:                         result.Append(int.Parse(currentNum.ToString()) + 1);
复制代码
  
  1.   58:                         result.Append(getMimimumUniqueNumByLength(temp.Length - i - 1));
复制代码
  
  1.   59:                         break;
复制代码
  
  1.   60:                     }
复制代码
  
  1.   61: 
复制代码
  
  1.   62:                 }
复制代码
  
  1.   63:                 else
复制代码
  
  1.   64:                 {
复制代码
  
  1.   65:                     result.Append(nextNum);
复制代码
  
  1.   66:                     if (i == temp.Length - 1)
复制代码
  
  1.   67:                     {
复制代码
  
  1.   68:                         result.Append(currentNum);
复制代码
  
  1.   69:                     }
复制代码
  
  1.   70:                 }
复制代码
  
  1.   71:             }
复制代码
  
  1.   72: 
复制代码
  
  1.   73:             var resultString = string.Empty;
复制代码
  
  1.   74: 
复制代码
  
  1.   75:             if (reach > 0)
复制代码
  
  1.   76:             {
复制代码
  
  1.   77:                 resultString = getAvaliableNum(long.Parse(result.ToString()));
复制代码
  
  1.   78:             }
复制代码
  
  1.   79:             else
复制代码
  
  1.   80:             {
复制代码
  
  1.   81:                 resultString = result.ToString();
复制代码
  
  1.   82:             }
复制代码
  
  1.   83:             return resultString;
复制代码
  
  1.   84:         }
复制代码
  
  1.   85: 
复制代码
  
  1.   86:         private static string getMimimumUniqueNumByLength(int length)
复制代码
  
  1.   87:         {
复制代码
  
  1.   88:             StringBuilder sb = new StringBuilder();
复制代码
  
  1.   89:             var temp = 0;
复制代码
  
  1.   90:             for (int i = 0; i < length; i++)
复制代码
  
  1.   91:             {
复制代码
  
  1.   92:                 sb.Append(temp);
复制代码
  
  1.   93:                 if (temp == 0)
复制代码
  
  1.   94:                 {
复制代码
  
  1.   95:                     temp = 1;
复制代码
  
  1.   96:                 }
复制代码
  
  1.   97:                 else if (temp == 1)
复制代码
  
  1.   98:                 {
复制代码
  
  1.   99:                     temp = 0;
复制代码
  
  1. 100:                 }
复制代码
  
  1. 101:             }
复制代码
  
  1. 102:             return sb.ToString();
复制代码
  
  1. 103:         }
复制代码
  
  1. 104:     }
复制代码
  
  1. 105: }
复制代码
结论

处理121989999991999只用一瞬间。就没有统计时间了。未进行溢出处理。
欢迎大家指正讨论。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册