【算法学习】几个数组相关的算法

	/**
	 * @Title: firstMissingPositive 
	 * @author: duanyd
	 * @Desc: 给一个数组,找到从1开始第一个不在里面的正整数。
	 * @date: 2018年11月28日 下午2:20:36
	 * @param A
	 * @param n
	 * @return
	 */
	int firstMissingPositive(int A[],int n){
		//[0...i) is  1...i
		for(int i = 0;i < n;){
			if(A[i] == i+1){
				++i;
			}else if((A[i]<=i)||(A[i]>n)||(A[A[i]-1]==A[i])){
				A[i] = A[--n];
			}else{
				swap(A[i],A[A[i]-1]);
			}
		}
		return n+1;
	}
	/**
	 * 
	 * @Title: swap 
	 * @author: duanyd
	 * @Desc: 交换函数 
	 * @date: 2018年11月28日 下午2:22:34
	 * @param a
	 * @param b
	 */
	void swap(int a,int b){
		int temp = a;
		a = b;
		b = temp;
	}
	/**
	 * 
	 * @Title: findTwoDigit 
	 * @author: duanyd
	 * @Desc: 一个数组,所有元素都出现了两次,只有两个数只出现了一次,求这两个数。
	 * 分析:所有数做异或,则出现两个次的数相抵消,那么最终的结果就是那两个出现一次的数x和y的异或结果,即x xor y ,
	 * 且这个值非0既然x xor y非0,我们可以找到二进制表示中某一个为1的位(bit)(例如最低位),
	 * 把所有的数按这位为1和为0分开。在该位为0和为1的数中,各有一个数只出现一次。 (一个是x,另一个是y)
	 * @date: 2018年11月28日 下午4:03:07
	 * @param a
	 * @param n
	 */
	void findTwoDigit(int a[],int n){
		int xXory = 0;
		for(int i=0;i < n; ++i){
			xXory^=a[i];
		}
		int mask = 1;
		for(;(xXory&mask) == 0;mask<<=1);
		int x = 0,y = 0;
		for(int i = 0;i < n; ++i){
			if(a[i]&mask){
				x ^= a[i];
			}else{
				y ^= a[i];
			}
		}
	}
	/**
	 * 	
	 * @Title: findModeNumber 
	 * @author: duanyd
	 * @Desc: 找出超过一半的数
	 * 分析:众数出现的次数大于其他所有数出现次数之和
		每次扔掉两个不同的数,众数不变
		如果扔掉一个众数,和一个非众数
		如果扔掉两个非众数
		如何实现?和x不同就扔掉,表示扔掉了一个x和一个y?
	 * @date: 2018年11月28日 下午4:10:24
	 * @param a
	 * @param n
	 * @return
	 */
	int findModeNumber(int a[],int n){
		int count=0,x = -1;
		for(int i=0;i < n; ++i){
			if(count == 0){
				x = a[i];
				count = 1;
			}else if(x == a[i]){
				++count;
			}else{
				--count;
			}
		}
		//注意有的题目要数一下x出现次数是否确实超过一半。(众数可能不存在)
		return x;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值