网易面试题目

1. 如果一个数字十进制表达时,不存在连续两位相同,则称之为“不重复数”。例如,105,1234,12121都是“不重复数”,而11,100,1225不是。给定一个long long类型数字A,返回大于A的最小“不重复数”。
  Constraints: A 取值范围是[0, 10^17],注意是闭区间。
  Examples:
    0) 54 Returns: 56
    1) 10 Returns: 12 
    2) 9  Returns: 10
    3) 98 Returns: 101
    4) 21099 Returns: 21201
  B=A+1
  B从高位往低位找第一个重复数字的位置, 没有返回B
  if 有 and not 99, 则把后面那个数字+1, 然后后面的为010101010....即可
  if 99, 则把X99变成(X+1) 01, 后面的也都是0101010....
  repeat until 没有重复数字为止
2.  输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来

  1). 如果n>m,则n中大于m的应该忽略,置n=m

  2). 将最大数n加入组合,如果n==m,直接输出

  3). 两种情况,n加入,在1到n-1中求子问题=m-n,n不加入,在1到n-1求子问题=m

void findEqual(unsigned n,int sum,int *flag)
{
    if(n<0 || m <0)
        return -1
    if(n>m)
        n=m
    if(n==m)
    {
        flag[n-1]=1
        printFlag(flag)
        flag[n-1]=0
    }

    flag[n-1]=0
    findEqual(n-1,m,flag)

    flag[n-1]=1
    findEqual(n-1,m-n,flag)
}

3.  一串首尾相连的珠子(m个), 有N种颜色(N<=10),设计算法,取出其中一段,要求包含所有N中颜色,并使长度最短。分析时间与空间复杂度。

  类似题目:给定一个很长的字符串str还有一个字符集比如{a,b,c}找出str里包含{a,b,c}的最短子串
  比如,字符集是a,b,c,字符串是abdcaabc,则最短子串为abc

  区别:前者带坏,后者不带环

  解法:两个指针pHead,pNext,用数组color记录当前已有颜色及其个数

  1). pNext++,直接color所有的颜色都出现,记录为最佳序列

  2). pHead++,相应的color的--,如果某个颜色的count=1,则和之前记录的最佳序列比较,更新最佳序列

  3). pHead++

  4). PNext++直接所有颜色都出现,重复2,3,4步骤

  其中,pNext=pNext%m

  结束条件:无环:pNext = m ,有环:pHead = m

4. 我们把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第1500个丑数。

  根据丑数的定义,丑数应该是另一个丑数乘以2、3或者5的结果(1除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数。里面的每一个丑数是前面的丑数乘以2、3或者5得到的。我们假设数组中已经有若干个丑数,排好序后存在数组中。我们把现有的最大丑数记做M。现在我们来生成下一个丑数,该丑数肯定是前面某一个丑数乘以2、3或者5的结果。我们首先考虑把已有的每个丑数乘以2。我们把得到的第一个乘以2后大于M的结果,记为M2,同样有M3M5。那么下一个丑数应该是M2M3M5三个数的最小者。

  前面我们分析的时候,提到把已有的每个丑数分别都乘以2、3和5,事实上是不需要的,因为已有的丑数是按顺序存在数组中的。对乘以2而言,肯定存在某一个丑数T2,排在它之前的每一个丑数乘以2得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以2得到的结果都会太大。我们只需要记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个T2。对乘以3和5而言,存在着同样的T3T5

  

int GetUglyNumber_Solution2(int index)
{
    if(index <= 0)
        return 0;
 
    int *pUglyNumbers = new int[index];
    pUglyNumbers[0] = 1;
    int nextUglyIndex = 1;
 
    int *pMultiply2 = pUglyNumbers;
    int *pMultiply3 = pUglyNumbers;
    int *pMultiply5 = pUglyNumbers;
 
    while(nextUglyIndex < index)
    {
        int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
        pUglyNumbers[nextUglyIndex] = min;
 
        while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply2;
        while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply3;
        while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply5;
 
        ++nextUglyIndex;
    }
 
    int ugly = pUglyNumbers[nextUglyIndex - 1];
    delete[] pUglyNumbers;
    return ugly;
}
 
int Min(int number1, int number2, int number3)
{
    int min = (number1 < number2) ? number1 : number2;
    min = (min < number3) ? min : number3;
 
    return min;
}

 4. 有A、B、C、D四个人,要在夜里过一座桥。通过这座桥分别需要耗时1、2、5、10分钟,只有一支手电,并且同时最多只能两个人一起过桥。请问,如何安排,能够在17分钟内这四个人都过桥?

  第一趟过去:两人:花1分钟和2分钟的人    //总共耗时:2分钟

  第一趟过来:一人:花1分钟的人              //总共耗时:3分钟
  第二趟过去:两人:花5分钟和10分钟的人    //总共耗时:13分钟
  第二趟过来:一人:花2分钟的人                 //总共耗时:15分钟

  第三趟过去:两人:花1分钟和2分钟的人      //总共耗时:17分钟

5. 地面上有无数的随机硬币,现在有一个人负责每天对这些硬币进行操作,操作如下:如果硬币是反面的,就把它翻过来;如果是正面的就随机抛一下;如此以往,到n天以后正面和反面的比例是否能够达到一个稳定的比例,如果能,求比例是多少。 

  假设硬币正面朝上为pos,反面朝上为neg,假设第n天处于pos状态的硬币数为an , neg状态的硬币数为bn,则最终所求的是an/bn 。

  由已知条件得:  

  an+1 = an/2 + bn
  bn+1 = an/2

  所以带入后,两边同除以an得到: 2an+1/an = 1+an-1/an

  由于是一个求极限问题,所以可以转化为:2x = 1+1/x

  又x不小于零,所以解得x = 1,所以: an/bn = 2an+1/an =2

  n天后将会达到极限值2

6.  如果一个整数能够表示成两个或多个素数之和,则得到一个素数和分解式。对于一个给定的整数,输出所有这种素数和分解式。注意,对于同构的分解只输出一次(比如5只有一个分解2 + 3,而3 + 2是2 + 3的同构分解式)。

  例如,对于整数8,可以作为如下三种分解: 
  (1) 8 = 2 + 2 + 2 + 2 
  (2) 8 = 2 + 3 + 3 
  (3) 8 = 3 + 5

  关键问题:得到小与n的所有素数表  

void GetPrimes(int n,vector<int>& Prime)
{
    Prime.push_back(2);
    for(int i=3;i<=n;++i)
    {
        int k;
        for(k=2;k*k<=i;++k)
            if(i%k==0)
                break;
        if(k*k>i)
            Prime.push_back(i);
    }
}
void Func(int n,int begin,vector<int>& Prime)
{
    static vector<int> V;
    if(n<0)
        return;
    else if(n==0)
    {
        for(vector<int>::iterator it=V.begin();it!=V.end();++it)
            cout <<*it<<" ";
        cout <<endl;
    }
    else
    {
        int num=Prime.size();
        //保证不同构
        for(int i=begin;i<num;++i)
        {
            V.push_back(Prime[i]);
            Func(n-Prime[i],i,Prime);
            V.pop_back();
        }
    }
} 

转载于:https://www.cnblogs.com/lbingkuai/p/4564491.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值