刷题记录0422

374. 猜数字大小 - 力扣(LeetCode)

继续二分专题 感觉已经比较熟练了

/** 
 * Forward declaration of guess API.
 * @param  num   your guess
 * @return 	     -1 if num is higher than the picked number
 *			      1 if num is lower than the picked number
 *               otherwise return 0
 * int guess(int num);
 */

class Solution {
public:
    int guessNumber(int n) {
        int i=1,j=n;
        while(i<=j)
        {
            int mid=(j-i)/2+i;
            if(guess(mid)==-1)
            {
                j=mid-1;
            }
            else if(guess(mid)==1)
            {
                i=mid+1;
            }
            else return mid;
        }
        return i;
    }
};

 1539. 第 k 个缺失的正整数 - 力扣(LeetCode)

这题数字量比较小 所以我选择了暴力,需要注意的是brr记得初始化为0,我开始没初始化样例没过

class Solution {
public:
    int findKthPositive(vector<int>& arr, int k) {
        int j=0;
        int len=arr.size();
        int brr[100010]={0};
        for(int i=0;i<len;i++)
        {
            brr[arr[i]]=1;
        }
        for(int i=1;i<=10000;i++)
        {
            if(brr[i]==0)j++;
            if(j==k)return i;
        }
        return 1;
    }
};

275. H 指数 II - 力扣(LeetCode)

理解h指数的含义,用二分法确定mid指向的数字是否等于(n-mid)即满足符合条件的论文数,

大于当前papers即right=mid-1;小于则left=mid+1;

class Solution {
public:
    int hIndex(vector<int>& citations) {
        int n = citations.size();
        int left = 0, right = n - 1;
        //利用数组已排序的特性,直接计算papers = n - mid
        //比较citations[mid]与papers的关系
        while (left <= right) {
            int mid = left + (right - left) / 2;
            int papers = n - mid; // 引用次数≥citations[mid]的论文数
            
            if (citations[mid] == papers) {
                return papers;
            } else if (citations[mid] < papers) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        //循环结束时,left指向第一个满足citations[i] >= n - i的位置
        //h指数即为n - left
        return n - left;
    }
};

483. 最小好进制 - 力扣(LeetCode)

这道hard我看的zerotrac题解,是题解里面第一个,目前还是太菜了,没有养成数学思维

然后deepseek写了一个二分法 要处理溢出问题 对我来说很难想到 感觉自己缺乏处理大数的经验

class Solution {
public:
    string smallestGoodBase(string n) {
        long long num=stol(n);
        long long ans=num-1;//如果没找到则是num-1进制,因为最后一个数字必定是1
        //s就是1的个数
        for(int s=59;s>=2;s--)
        {
            //k是进制数
            int k= pow(num,1.0/s);
            if(k>1)
            {
                long long sum=1,mul=1;//sum底数为1是因为最小位数为1
                //计算k进制数字和,因为底数为1所以mul*=k;
                for(int i=1;i<=s;i++)
                {
                    mul*=k;
                    sum+=mul;
                }
                //如果找到了返回k
                if(sum==num)
                {
                    ans=k;
                    break;
                }
            }
        }
        return to_string(ans);
    }
};

//deepseek写的二分法也可参考 
class Solution {
public:
    string smallestGoodBase(string n) {
        long long num = stol(n);
        long long ans = num - 1; // 最大可能的进制
        // s表示1的个数(从大到小枚举)
        for (int s = log2(num) + 1; s >= 2; s--) {
            // 对每个s,用二分法找k
            
            //2进制到 num的1/(s-1)进制
            long long left = 2, right = pow(num, 1.0/(s-1)) + 1;
            while (left <= right) {
                long long mid = left + (right - left) / 2;
                long long sum = 0;
                
                // 用等比数列求和公式计算
                bool overflow = false;
                for (int i = 0; i < s; i++) {
                    if (sum > (num - 1) / mid) { // 防溢出检查
                        overflow = true;
                        break;
                    }
                    sum = sum * mid + 1;
                }
                
                if (overflow || sum > num) {
                    right = mid - 1;
                } else if (sum < num) {
                    left = mid + 1;
                } else {
                    return to_string(mid);
                }
            }
        }
        
        return to_string(ans);
    }
};

1201. 丑数 III - 力扣(LeetCode)

先计算个数 在二分法

#include <algorithm>
using namespace std;

class Solution {
public:
    // 计算两个数的最小公倍数
    long long lcm(long long x, long long y) {
        return x * y / gcd(x, y);
    }

    // 计算在[1, x]区间内,能被a、b、c之一整除的数的个数
    long long count(long long x, long long a, long long b, long long c) {
        return x / a + x / b + x / c
            - x / lcm(a, b) - x / lcm(b, c) - x / lcm(a, c)
            + x / lcm(a, lcm(b, c));
    }

    int nthUglyNumber(int n, int a, int b, int c) {
        long long left = 1, right = 2e9;
        
        while (left < right) {
            long long mid = left + (right - left) / 2;
            if (count(mid, a, b, c) >= n) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }

        return left;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值