• 编程之美题选


    1、求二进制数中1的个数:
    1、除以2 根据余数 判断,迭代
    2、与1相与,根据结果判断,循环移位
    3、列出全部数据映射2-1 3-2 4-1 。。。 建立Hash表O(1)

    4、(1100&1011=1000 能去掉最右边的1)
       intNumber(int n ){
          int count=0;
          while(n){
          count++;
          n=(n-1)&n;
        }
      }


    2、求出数组中个数超过一半的数字A
    每次删除2个不同的数字,那么在剩下的数字中,A仍会超过总数的一半。

    int find(int ID[], int n){
        int nTimes = 0, i, candidate;
        for(i = 0; i < n;i++){
            if(nTimes == 0){
                candidate = ID[i];
                nTimes = 1;
            }
            else{
                if(candidate == ID[i])
                    nTimes++;
                else
                    nTimes--;
            }
        }
        return candidate;
    }

    现在有3个发帖水王,发帖数目都超过了总数的1/4,怎么找出这三个人?
    现在我们需要3个变量来记录当前遍历过的3个不同的ID,而nTimes的3个元素分别对应当前遍历过的3个ID出现的个数。如果遍历中有某个ID不同
    于这3个当前ID,我们就判断当前3个ID是否有某个的nTimes为0,如果有,那这个新遍历的ID就取而代之,并赋1为它的遍历数(即nTimes减1)
    ,如果当前3个ID的nTimes皆不为0,则3个ID的nTimes皆减去1。

    3、n个数字中取出前K大的数;
    方法一:
    1、用快排的思想,a[0]为基准,划分数组为Sa都大于a[0],Sb都小于a[0]
    2、若|Sa|<K,则Sa中的所有数加上Sb中的K-|Sa|个数就是数组的前K大
    3、若|Sa|>K,则Sa中的前K个数就是数组的前K大
    4、这样递归下去,不断把问题分解为更小的子问题,平均复杂度为O(N*logK)
    方法二:
    用最小堆时间复杂度也是O(N*logK)
    空间复杂度是O(K)
    在N非常大,数据需要存储在磁盘上,而K相对很小,可以在内存上轻易维护大小为K的堆的情况下,在减少磁盘I/O上会有一定的优势,因为每个
    元素只需要被读取一次。

    4、得到数组的最大值和最小值:
    方法一:每2个数字比较,大的放在偶数位,小的在奇数位,在各自求极值,1.5N的复杂度
    方法二:每2个数字比较,大的再和MAX比较,小的再和MIN比较,不用破坏数组,也是1.5N。
    方法三:也可以用分治,求前后N/2的MIN和MAX,小小比较得到MIN,大大比较得到MAX,递归

    5、求二维平面上N个点,距离最小的2点
    方法一:穷举O(n^2)
    方法二:分治法,中点x对半分成2个区域,分别求最小得出min,但可能出现左右2边有2点间距最小,只考虑在[x-min,x+min]内的点,以此解法
    递归求解

    数组中取出2个数的和等于给定值A
    方法一:O(n^2) a[i]+a[j]==A? 或者用a[j]==A-a[i]?
    方法二:消耗O(n)的空间存储Hash表,根据映射查找A-a[i]是否在表中
    方法三:先排序O(nlogn),再用双指针left(0), right(n-1)指向2端,若之和大于A则right移动
    否则left移动。


    6、N-1子数组的最大乘积
    不急分情况讨论:(N个数的乘积)
    1、p=0 再分情况:q为N-1个数的乘积
    q=0解为0
    q<0解为0
    q>0为解
    2、p<0去掉绝对值最小的那个负数即可
    3、p>0去掉绝对值最小的那个正数
    (+暴力破解)O(n^2)

    7、求子数组最大和:
    方法一:暴力O(n^3)
    方法二:分治法:
    A[n]最大字段和值为三种情况:
    1、A[n/2-1]的最大字段和
    2、A[n/2]到A[n]的最大字段和
    3、最大字段和横跨A[n/2-1]和A[n/2](卡中间,计算Sum=sum1+sum2)

    方法三:动态规划法
    //如果sum>Max 则更新Max
    //如果sum<0 则 更新sum为0 继续循环
    //否则是0<sum<Max 说明sum是有潜力的,后来可能会更新为更大的值

    for(int i=1;i<=t;i++){
    sum+=a[i];//sum存储当前最大的b[j], b存储b[j]
    if(sum>Max)Max=sum;
    if(sum<0)sum=0;
    }
    //Max存储全局最大,sum随着指针移动而变化,为负数则置0
    //找到更大的则赋给Max,Max始终存储全局最大

    8、求数组中最长递增子序列:
    前i个元素中最长递增子序列为LIS[i]
    则有:LIS[i+1]=max{1,LIS[k]+1}

    for(int i=0;i<arr.length;i++){
    	LIS[i]=1;
    	for(int j=0;j<i;j++){
    		if(arr[i]>arr[j]&&LIS[j]+1>LIS[i])
    			LIS[i]=LIS[j]+1;
    	}
    }
    return Max(LIS); 
    

    9、数组循环右移K位,复杂度O(n),最多允许使用2个变量
    abcd1234右移4位->1234abcd
    前4位逆序排列 abcd1234->dcba1234
    后4位逆序排列dcba1234->dcba4321
    全部逆序dcba4321->1234abcd

    Reverse(int* arr,int b,int e){
    	for(;b<e;b++,e--){
    		int temp=arr[e];
    		arr[e]=arr[b];
    		arr[b]=temp;
    	}
    }
    RightShift(int* arr,int N,int k){
    	K%=N;
    	Reverse(arr,0,N-K-1);
    	Reverse(arr,N-K,N-1);
    	Reverse(arr,0,N-1);
    }
    

    (没要求空间复杂度才可以创建一个新的数组直接O(N)copy过去)
    一位一位移动的复杂度是O(K*N)

    10、数组分割:使得2份之和 尽量接近


    11、字符串移位包含:
    1、暴力破解
    2、判断s2是否是s1的移位包含,可以将2个s1连起来以避免移位。
    AABCD AABCD包CDAA 空间换时间

    12、从无头单链表中删除节点:
    假设一个没有头指针的单链表。一个指针指向此单链表中间的一个节点p(不头不尾),要删除该节点p
    "狸猫换太子":可以把p节点后面的节点q的value赋值到p节点,
    然后删除节点q即可
    q=p-next;
    p->data=q->data;
    p-next=q-next;

    13、判断2个链表a,b是否相交:
    1、暴力解法 依次判断a中节点是否在b中,复杂度O(length(a)*length(b))
    2、用hash建立其中一个链表的节点地址查询hash表
    3、可以将b链表表头连接在a表的后面,在判断链表是否有环
    4、直接判断最后一个节点是否是同一节点,复杂度O(length(a)+length(b))是最快捷的解法

    (怎样找到第一个公共结点?)链表长的-短的=i  长的先走i步,然后一起走,每步判断结点是否相同

    14、重建二叉树:根据前序和中序


    15、分层遍历二叉树:

  • 相关阅读:
    GridView“GridView1”激发了未处理的事件“RowDeleting”
    遮罩层提示框,可拖动标题栏(兼容FF)
    JS判断IE,FF等浏览器类型
    DataGrid GridView 隔行换色 鼠标经过改变背景色
    常用js函数Common.js
    GridView和DataFormatString 日期格式 精确小数点后位数
    常用js函数CheckData.js
    图像处理技术
    VS Code中编写html(5) 标签的布局设置
    产品经理应该具备的技能(1)
  • 原文地址:https://www.cnblogs.com/gaoxiangde/p/4356891.html
Copyright © 2020-2023  润新知