美团2016招聘笔试:奇数位丢弃

美团2016招聘笔试:奇数位丢弃

对于一个由0…n的所有数按升序组成的序列,我们要进行一些筛选,每次我们取当前所有数字中从小到大的第奇数位个的数,并将其丢弃。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。

输入描述:

每组数据一行一个数字,为题目中的n(n小于等于1000)。

输出描述:

一行输出最后剩下的数字。

输入例子:

500

输出例子:

255

方法一:常规解法,将数组不断更新,每一次去除奇位数的元素,直至数组的长度为1,输出即可。
算法复杂度:
T(n) = n + n/2 + n/4 +…1 = 2^n-1
故为O(2^n)
时间复杂度:
O(n)
代码:(偷个懒写个python版)

n = int(input())
lis = [i for i in range(0,n+1)]
while len(lis)!=1:
    lis = [i for i in lis if (lis.index(i)+1)%2==0]
print(lis)

方法二:利用二进制巧妙解法
思路:
我们发现,每一次删除的元素都是对应下标位置的二进制最右端为0的元素,列如0(二进制为0),2(二进制为10),4(二进制为100)。剩余的元素例如1(01),3(11),5(101)在下一次的变换中对应的二进制下标为原二进制下标左移一位之后的1(1),3(10),5(10)之后继续删除对应下标的二进制数的最右端为0的元素。所以最后剩下的元素,一定是从右往左数二进制数中含1最多的元素,因为每一次删除移位后最右端都为1,会被一直保留下来
算法复杂度:
O(n)
空间复杂度:
O(1)

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int x = 1;
	while( x <= n )
		x = x*2 +1;
	cout << (x>>1) << endl;
}

方法三:数学公式法
分析可知,每一次减少一半的数据,经过long(n)(向下取整)次减少到只有一个数。那么只有2^floor(log(n)) 或者 2^floor(log(n))-1 能够经过long(n)次的向下取整之后得到1.因为在第一次删除时,已经去除所有的偶数,因此排除2log(n))。所以这个数为2log(n))-1
算法复杂度:
时间复杂度:O(1)
空间复杂度:O(1)

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	cout<<(int)pow(2,floor(log2(n)))-1<<endl;
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值