判断两个数是否互质;409. 最长回文串;面试题 01.06. 字符串压缩;面试题 17.16. 按摩师

bool gcd(int a,int b){
    if(a==1||b==1)return true;
    if(b==0)return false;
    return helper1(b,a%b);
}

 

给定N和K,求互不相同的正整数x,y,z使得x+y+z=N,且gcd(x,y)=gcd(x,z)=gcd(y,z)=K。

条件:1 ≤N, K≤ 1e18

思路:等式两边除K,得到x'+y'+z'=N'=N/K,且x',y',z'两两互素。

当N'为偶数,直接构造x'=1, y'=N'/2, z' = y'-1满足条件。

当N'为奇数,另x'=1,则y'+z'=N'-1。由于N'-1为偶数且y'和z'互素,必然有y',z'都为奇数。令y'=3,5,..., N' / 2逐个搜索即可。

 

在这里讨论一下N'为奇数时搜索的复杂度。

考虑奇素数pi,如果y'=pi不满足条件,那么必然有z'与pi不互素,也就是pi整除z',从而pi整除pi+z'=N'-1

考虑y'为前15个奇素数p1,...,p15。如果均不满足条件,那么他们的乘积p1p2...p15也整除N'-1。考虑到前15个奇素数的积已经超过了1e18,矛盾。

因此我们搜索到第15个奇素数(53)的时候一定能找到一对满足条件的y'和z'。因此搜索复杂度为O(p15)=O(1)。

 

判断两个数是否互质;409. 最长回文串;面试题 01.06. 字符串压缩;面试题 17.16. 按摩师_第1张图片

作者:tuogy
链接:https://www.nowcoder.com/discuss/455801
来源:牛客网
 

求区间[l, r]内的幸运数。幸运数定义为,将相邻数位差的绝对值拼成下一个数,重复该操作直到只剩1位。剩下7的是幸运数。例如,219->18->7或者118->7

条件:1 ≤ l ≤ r ≤ 1e9

思路:根据1,...,k-1位的幸运数,给定首位数字,可以搜索得到k位的幸运数。将所有幸运数排序后进行二分查找。

 

因为每一个更长的幸运数都可以通过题目里规定的操作变成一个更短的幸运数,反过来讲,给定每个幸运数的首位 for i in {1, ..., 9},它都可以通过一个比他短的幸运数计算得到。

比如给定首位是1,可以算 7->18。根据18,给定首位是2,又可以算出18->219。

不断这样以小算大,可以算出所有幸运数。

注意k位的幸运数不仅可以通过k-1的幸运数计算得到,还可以通过更短的幸运数在前方补0到k-1位后计算得到。例如:7补成007,可以计算得到1118,2229,7770,8881,9992。

判断两个数是否互质;409. 最长回文串;面试题 01.06. 字符串压缩;面试题 17.16. 按摩师_第2张图片

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意:
假设字符串的长度不会超过 1010。

示例 1: 

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

class Solution {//审题
public:
    int longestPalindrome(string s) {
        unordered_mapm;
        for(auto &i:s)
            ++m[i];
        bool b=false;
        int res=0;
        for(auto &i:m){
            if((i.second&1))b=true;
            res+=i.second>>1<<1;
        }
        res+=b?1:0;
        return res;
    }
};

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

 示例1:

 输入:"aabcccccaaa"
 输出:"a2b1c5a3"


 示例2:

 输入:"abbccd"
 输出:"abbccd"
 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。


提示:


字符串长度在[0, 50000]范围内。

class Solution {
public:
    string compressString(string S){
        if(S.size()<=2)return S;
        string res;
        int cnt=1;
        for(int i=1;i=S.size())return S;
                cnt=1;
            }
        res+=S[S.size()-1]+to_string(cnt);
        return res.size()v;
        s+=S[0];
        v.push_back(1);
        for(int i=1,j=0;i

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。

注意:本题相对原题稍作改动

 

示例 1:

输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。


示例 2:

输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。


示例 3:

输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。

class Solution {
public:
    int massage(vector& nums){
        if(nums.size()==0)return 0;
        if(nums.size()==1)return nums[0];
        int a=0,b=nums[0];
        for(int i=1,tmp;i& nums) {
        if(nums.size()==0)return 0;
        if(nums.size()==1)return nums[0];
        vector>dp(nums.size(),vector(2,0));
        dp[0][0]=0;
        dp[0][1]=nums[0];
        for(int i=1;i

 

你可能感兴趣的:(LeetCode)