校招算法笔面试 | 校招笔面试真题-奇数位丢弃

题目

题目链接

解题思路

这是一道数学规律题,主要思路如下:

  1. 问题分析:

    • 0 … n 0 \dots n 0n 的序列,每次丢弃奇数位置的数
    • 需要找到最后剩下的数字
    • 例如:对于 n = 500 n=500 n=500,最后剩下 255 255 255
  2. 解决方案:

    • 观察规律可以发现,最后剩下的数是小于等于 n n n 的最大2的幂次数减1
    • 通过位运算可以快速求解:
      1. 找到大于 n n n 的最小2的幂
      2. 将该数除以2再减1即为答案
  3. 数学证明:

    • 每次删除奇数位后,剩余数字形成新序列
    • 新序列的规律符合2的幂次数减1的形式

代码

#include <iostream>
using namespace std;

int findLastNumber(int n) {
    // 找到大于n的最小2的幂
    int power = 1;
    while (power <= n + 1) {
        power <<= 1;
    }
    // 返回该2的幂除以2再减1
    return (power >> 1) - 1;
}

int main() {
    int n;
    while (cin >> n) {
        cout << findLastNumber(n) << endl;
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static int findLastNumber(int n) {
        // 找到大于n的最小2的幂
        int power = 1;
        while (power <= n + 1) {
            power <<= 1;
        }
        // 返回该2的幂除以2再减1
        return (power >> 1) - 1;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            System.out.println(findLastNumber(n));
        }
    }
}
def find_last_number(n: int) -> int:
    # 找到大于n的最小2的幂
    power = 1
    while power <= n + 1:
        power <<= 1
    # 返回该2的幂除以2再减1
    return (power >> 1) - 1

# 处理输入
while True:
    try:
        n = int(input())
        print(find_last_number(n))
    except EOFError:
        break

算法及复杂度

  • 算法:位运算
  • 时间复杂度: O ( log ⁡ n ) \mathcal{O}(\log n) O(logn) - 需要循环 log ⁡ n \log n logn 次找到合适的2的幂
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要常数额外空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值