zoukankan      html  css  js  c++  java
  • MS100 [061070]

    MS100 [061]

    找出数组中两个只出现一次的数字

    题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。

    请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

    思路:使用异或运算。

    第一遍,全部异或,得到A,A中至少有一位为1,记为t位。

    第二遍,对数组中的任意一个数,若t位为1,则与C异或,若t位为0,则与D异或。最后的C,D即为所求。

    MS100 [062]

    找出链表的第一个公共结点
    题目:两个单向链表,找出它们的第一个公共结点。

    思路:第一遍遍历两个链表,若尾指针相同则相交(若是循环链表,取任意一个循环中的节点即可),并且得到两个链表的长度。第二遍先让长的链表遍历他们的差值步,然后同步遍历两个链表,并比较是否相等。

    MS100 [064]

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

    思路:根据定义可知,后面的丑数肯定是前面已知丑数乘以235得到的。

      我们假设一个数组中已经有若干丑数,并且这些丑数是按顺序排列的,我们把现有的最大丑数记为max,则下一个丑数肯定是前面丑数乘以235得到的。不妨考虑乘以2得到的情况,我们把数组中的每一个数都乘以2,由于原数组是有序的,因为乘以2后也是有序递增的,这样必然存在一个数M2,它前面的每一个数都是小于等于max,而包括M2在内的后面的数都是大于max的,因为我们还是要保持递增顺序,所以我们取第一个大于max的数M2。同理对于乘以3的情况,可以取第一个大于max的数M3,对于乘以5的情况,可以取第一个大于max的数M5

      最终下一个丑数取:min{M2,M3,M5}即可

    int mymin(int a, int b, int c)   
    {   
        int temp = (a < b ? a : b);   
        return (temp < c ? temp : c);   
    }   
    int FindUgly(int n) //
    {   
        int* ugly = new int[n];   
        ugly[0] = 1;   
        int index2 = 0;   
        int index3 = 0;   
        int index5 = 0;   
        int index = 1;   
        while (index < n)   
        {   
            int val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5); //竞争产生下一个丑数   
            if (val == ugly[index2]*2) //只需要产生这个丑数的index*向后挪一位,因为其他数字必定比当前的丑数大。
                ++index2;   
            if (val == ugly[index3]*3)   //这里不能用elseif,因为可能有两个最小值,这时都要挪动;
                ++index3;   
            if (val == ugly[index5]*5)   
                ++index5;   
            ugly[index++] = val;   
        }   
     /*/
        for (int i = 0; i < n; ++i)   
            cout << ugly[i] << endl;   
     //*/
        int result = ugly[n-1];   
        delete[] ugly;   
        return result;   
    }  
    MS100 [065]

    输出1 到最大的N 位数
    题目:输入数字n,按顺序输出从1 最大的n 位10 进制数。比如输入3,则输出1、2、3 一直到最大的3 位数即999。

    思路:(自己想的)考虑到N可能无限大,设置一个N位的数组,然后采用递归的方式,每次递归给当前位增加1,然后递归到下一位中,在最后一位时输出。注意若高位为0,则不输出。

    #include <iostream>
    using namespace std;
    void Output(int* a,int n,int index){
    	if(index == n){
    		int first = -1;
    		while(a[++first] == 0);
    		for(int i=first;i<n;i++)cout<<a[i];
    		cout<<endl;
    		return;
    	}
    	for(int i=0;i<=9;i++){
    		a[index]=i;
    		Output(a,n,index+1);
    	}
    }
    int main(){
        int n;
    	cin>>n;
    	int* a = new int[n];
    	Output(a,n,0);
    	return 0;
    }
    MS100 [066]

    颠倒栈
    题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1 在栈顶。
    颠倒之后的栈为{5, 4, 3, 2, 1},5 处在栈顶。

    思路:直接递归,每次把栈顶的元素移到pop出这个元素后的栈的底部。

    void Reverse(Stack stack){
        if(!stack.empty()){
            Object o = stack.pop();
            Reverse(stack);
            InsertToBottom(stack,o);
        }
    }
    void InsertToBottom(Stack stack,Object o){
        if(stack.empty()){
            stack.push(o);
        }
        else{
            Object o2 = stack.pop();
            InsertToBottom(stack,o);
            stack.push(o);
        }
    }

    MS100 [068]
    把数组排成最小的数

    题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的
    一个。
    例如输入数组{32, 321},则输出这两个能排成的最小数字32132。
    请给出解决问题的算法,并证明该算法。
    思路:相当于给数组中的元素排序,取min(a,b)为ab和ba中的较小值。由于要考虑溢出问题,所以可以分两段考虑。

  • 相关阅读:
    anaconda 离线安装大包
    Openpose 安装问题解决
    Linux grep log文件及find命令学习
    整理了一些常用编程软件(方便自己下载)
    Docker安装es7.6和kibana7.6(并解决Unable to revive connection: http://192.168.162.139:9200/的问题)
    Jsr303分组校验和自定义注解校验
    Spring Cloud整合Oss
    Linux:vim
    Linux:挂载命令
    SpringBoot整合SpringSecurity:集中式项目
  • 原文地址:https://www.cnblogs.com/zhuyuanhao/p/3262871.html
Copyright © 2011-2022 走看看