这两天闲暇,回过头来看看一些基本的算法,发现还有很多可以优化的地方.记不清此题的出处了,好像是某大厂面试题,网上也有很多算法了,其中一些大神的算法看的心旷神怡,茅塞顿开,禁不住手痒也凑凑热闹:

体的本意是在1-10000中缺失了一个数组,请写算法找出这个数字,当然了时间复杂度,空间复杂度越低越好.

1.最简单的算法就是创建一个数组,数组的大小可以为10000个,然后在这9999个数里面找打那个就给那个数组做个记号,方法直接,容易理解,就是空间复杂度有点高.

2.就是计算出1-10000的和,然后逐个减去这些数,最后的结果就是缺失的数字,空间复杂度,时间复杂度都不高,确实是个好办法.唯一的问题就是,如果不是10000,而是很大的一个数字呢?会不会溢出?当然这些可以进行控制,比如分段计算,但这样时间复杂度会高一些.

3.然后就是大牛的算法,对1-10000逐个异或操作,然后结果在对给定的数逐个异或,最后的结果就是缺失的数字,这直接进行位运算,即使分成两次循环,时间复杂度也不过O(N*2),如果把这两个计算放到同一个循环中,那时间复杂度也就是O(N),空间复杂度O(1).真是完美.相关算法如下:

//count为N-1,是数组元素的个数
int Search(int* p, int count)
{int ret = 0;int i;for(i=0;i<count;i++){ret ^= (i + 1);ret ^= *(p + i);}ret ^= count + 1;return ret ;
}

4.然后我们在思考一下?0^1^2^3=0,4^5^6^7=0,8^9^10^11=0....然后发现每组4个数异或的结果都为0,既然这样我们为什么还要从1异或到10000在对数据进行异或求结果呢?看来我们可以省下很多步计算了.代码如下:

int NewSearch(int* p, int count)
{int ret = 0;int t = (count + 1) % 4;int i;for (i = count + 1; i > count - t; i--){ret ^= i;}for (i = 0; i < count; i++){ret ^= *(p + i);}return ret;
}

这样,总体的计算就少了很多,尤其是当N很大的时候,更加明显.

全部代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#define WIN32
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#ifdef WIN32
#include<windows.h>
#else
#include<sys/time.h>
#endif
#ifdef WIN32
int gettimeofday(struct timeval* tp, void* tzp)
{time_t clock;struct tm tm;SYSTEMTIME wtm;GetLocalTime(&wtm);tm.tm_year = wtm.wYear - 1900;tm.tm_mon = wtm.wMonth - 1;tm.tm_mday = wtm.wDay;tm.tm_hour = wtm.wHour;tm.tm_min = wtm.wMinute;tm.tm_sec = wtm.wSecond;tm.tm_isdst = -1;clock = mktime(&tm);tp->tv_sec = (long)clock;tp->tv_usec = wtm.wMilliseconds * 1000;return(0);
}
#endifstruct timezone
{int tz_mainuteswest;int tz_dsttime;
};void createArr(int* p,int count)
{int r = 1+rand()%(count+1);int j;for (j = 1; j <= count; j++){if (j < r) {*(p++) = j ;}else{*(p++) = j + 1;}}
}void shuffle(int* p , int count)
{int i = count;int j ,tmp;while (i){j = rand() % (i--);tmp =*(p+j);*(p+j) = *(p+i);*(p+i) = tmp;}
}//优化后的算法
int NewSearch(int* p, int count)
{int ret = 0;int t = (count + 1) % 4;int i;for (i = count + 1; i > count - t; i--){ret ^= i;}for (i = 0; i < count; i++){ret ^= *(p + i);}return ret;
}//很牛的算法
int Search(int* p, int count)
{int ret = 0;int i;for(i=0;i<count;i++){ret ^= (i + 1);ret ^= *(p + i);}ret ^= count + 1;return ret ;
}int main()
{//设置随机数种子srand((int)time(0));int count = 999999999;int *arr =(int*)malloc(count*sizeof(int));//生成顺序的数组createArr(arr, count);//乱序一下shuffle(arr, count);struct timeval tv1, tv2;struct timezone tz;//开始计时gettimeofday(&tv1, &tz);int ret= Search(arr, count);gettimeofday(&tv2, &tz);printf("缺失的数字是:%d\n", ret);//计算用时int ms=(int)((tv2.tv_usec - tv1.tv_usec)/1000);ms = tv2.tv_usec > tv1.tv_usec ? ms : ms + 1000;int s = tv2.tv_usec > tv1.tv_usec ? (int)(tv2.tv_sec - tv1.tv_sec) : (int)(tv2.tv_sec - tv1.tv_sec - 1);printf("用时%d秒,%d毫秒\n", s, ms);//开始计时gettimeofday(&tv1, &tz);ret = NewSearch(arr, count);gettimeofday(&tv2, &tz);printf("缺失的数字是:%d\n", ret);//计算用时ms = (int)((tv2.tv_usec - tv1.tv_usec) / 1000);ms = tv2.tv_usec > tv1.tv_usec ? ms : ms + 1000;s = tv2.tv_usec > tv1.tv_usec ? (int)(tv2.tv_sec - tv1.tv_sec) : (int)(tv2.tv_sec - tv1.tv_sec - 1);printf("用时%d秒,%d毫秒\n", s, ms);return 0;
}

关于1-n中缺失的1个数字算法的优化相关推荐

  1. 程序员面试题精选100题(47)-数组中出现次数超过一半的数字[算法]

    题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字. 分析:这是一道广为流传的面试题,包括百度.微软和Google在内的多家公司都曾经采用过这个题目.要几十分钟的时间里很好地解答这道题 ...

  2. 在线段裁剪算法中是否能对区域编码算法进行优化实现模式的唯一判别呢

    在线段裁剪算法中是否能对区域编码算法 来进行优化实现模式的唯一判别呢 是否可以直接判断直线段和裁剪区域的相对关系呢

  3. 【ShareCode】不错的技术文章 -- 如何使用异或(XOR)运算找到数组中缺失的数?...

    如何使用异或(XOR)运算找到数组中缺失的数? 今天给大家分享一篇关于使用XOR(异或)运算找到数组中缺失的数的问题. 在一次Javascript面试中,有这么一个问题: 假设有一个由0到99(包含9 ...

  4. LeetCode-剑指 Offer 53 - II. 0~n-1中缺失的数字

    剑指 Offer 53 - II. 0-n-1中缺失的数字 思路一:简单for循环找 class Solution {public:int missingNumber(vector<int> ...

  5. xp可以装java6不_XP系统XMind 6中缺失安装java环境

    在安装使用 XMind 6的过程中,因为系统的不同,电脑环境不一样,会影响XMind 6正常使用.就拿安装XMind 6 java来说,安装环境的缺失也可能导致失败,本文就讲解了XP系统XMind 6 ...

  6. 【算法】剑指 Offer 53 - II. 0~n-1中缺失的数字

    1.概述 剑指 Offer 53 - II. 0-n-1中缺失的数字 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一 ...

  7. 0-n-1中缺失的数字

    0-n-1中缺失的数字 一共N个数范围在0 ~ n-1 之间: 但是数组的长度只是n - 1 所以有一个数缺失了,找出那个缺失的数字. 有两个关键信息: 数组是有序的,递增 数字都是唯一的,就少一个数 ...

  8. 剑指 Offer 53 - II. 0~n-1中缺失的数字(二分查找)

    /*** 剑指 Offer 53 - II. 0-n-1中缺失的数字* @author wsq* @date 2020/10/08一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在 ...

  9. (源码)CAD二次开发—实现AutoCAD中缺失字体自动替换

    使用C# 实现AutoCAD中缺失字体的自动替换 设计思路: 获取到当前字体样式的设计集合 遍历所有的字体样式,对对应的字体样式进行查找 如果找不到则进行替换 namespace AutoCADTo ...

最新文章

  1. js表单验证,如果不为空时自动改变提交按钮的背景色
  2. 加速 cinder 删除volume速度
  3. cctype 头文件定义函数实例
  4. 用python画图-用python进行简单的画图操作
  5. Bayesian Networks
  6. 如何使用eclipse创建项目
  7. MFC CListCtrl 取消选中
  8. linux unshare 命令,详解Linux Namespace之User
  9. Linux6、7 系列 安装、卸载mysql
  10. MySQL 语句优化 ICP
  11. 薄板样条插值(Thin Plate Spline)
  12. Android 各大市场更改APP名称
  13. 制作轮播切换效果html,原生JS实现图片轮播切换效果
  14. ccProxy软件实现网络共享
  15. docker服务假死解决方案
  16. 基于MATLAB的数字证件号识别
  17. 【简单实用】一台主机两个人使用,互不影响~~~
  18. 晕菜..调试的死机..
  19. 一名大学毕业生的反思(转)
  20. V880/N880/N880S USB调试模式开启方法

热门文章

  1. 北京交管部门多举措进行二环慢行系统改造,提升通行安全与效率
  2. Kali linux安装Nvidia官方显卡驱动的心灵路程
  3. java 空格 separater_Java随手记
  4. 几款好用证件照制作工具推荐
  5. coco数据集分割可视化格式转换
  6. 小哈智能机器人的功能_小哈智能教育机器人H2产品外观参数说明
  7. vue集成Luckyexcel实现在线编辑Excel,可自行导入,也可从服务器端获取
  8. 如何在 Ubuntu 和其他 Linux 发行版中启动、停止和重启服务
  9. MAX9286+MAX96705高级辅助驾驶系统ADAS方案
  10. 01超精美渐变色动态背景完整示例【CSS动效实战(纯CSS与JS动效)】