leetcode 268周赛总结

T4:k 镜像数字的和

在这里插入图片描述

  • 暴力的代码(不断迭代生成十进制回文数值)
  • 利用回文数值的递归形式
  • 两边加入相同的数,中间从小到大插入n - 2位的数,其中n是当前欲生成回文数的位数
class Solution {

    public boolean isparlid(String s)
    {
        int low = 0;
        int high = s.length() - 1;
        while(low<=high)
        {
            if(s.charAt(low) == s.charAt(high))
            {
                low++;
                high--;
            }
            else return false;
        }
        return true;
    }

    /**
     * 将十进制数转换为k进制数
     * @param n
     * @return
     */
    public String DtoK(long n,int K)
    {
        StringBuilder s = new StringBuilder();
        do
        {
            s.insert(0,n%K);
            n/=K;
        }while(n!=0);
        return s.toString();
    }


    public long kMirror(int k, int n) {
        //从小到大生成回文数
        Map<Integer,List<String>> temp = new HashMap<>();
        //一位数
        long ans = 0;
        int count = 0;
        temp.put(1,new ArrayList<>());
        temp.get(1).add("0");
        for(int i = 1;i<=9;i++)
        {
            temp.get(1).add(Character.valueOf((char)(i + '0')).toString());
            if(isparlid(DtoK((long)i,k))) {
                ans += i;
                count++;
                System.out.println(i);
                if(count == n)
                    return ans;
            }
        }
        //两位数
        temp.put(2,new ArrayList<>());
        temp.get(2).add("00");
        for(int i = 11;i<=99;i+=11)
        {
            temp.get(2).add(Integer.valueOf(i).toString());
            if(isparlid(DtoK(i,k)))
            {
                ans+=i;
                count++;
                System.out.println(i);
                if(count == n)
                    return ans;
            }
        }
        //三位数开始递归利用前面的构造
        for(int i = 3;;i++)
        {
            temp.put(i,new ArrayList<>());
            for(char j = '0';j<='9';j++)
            {
                for(String a : temp.get(i - 2))
                {
                    String b  = j + a + j;
                    temp.get(i).add(b);
                    if(j!='0' && isparlid(DtoK(Long.parseLong(b),k)))
                    {
                        System.out.println(b);
                        ans+=Long.parseLong(b);
                        count++;
                        if(count == n)
                            return ans;
                    }
                }
            }
        }
    }

//    public static void main(String[] args)
//    {
//        System.out.println(new Solution().DtoK(6958596,7));
//        new Solution().kMirror(7,17);
//    }
}

优化1(二分搜索)

优化2(打表 不多说)

class Solution {
private:
    static constexpr long long ans[][30] = {
        {1, 3, 5, 7, 9, 33, 99, 313, 585, 717, 7447, 9009, 15351, 32223, 39993, 53235, 53835, 73737, 585585, 1758571, 1934391, 1979791, 3129213, 5071705, 5259525, 5841485, 13500531, 719848917, 910373019, 939474939},
        {1, 2, 4, 8, 121, 151, 212, 242, 484, 656, 757, 29092, 48884, 74647, 75457, 76267, 92929, 93739, 848848, 1521251, 2985892, 4022204, 4219124, 4251524, 4287824, 5737375, 7875787, 7949497, 27711772, 83155138},
        {1, 2, 3, 5, 55, 373, 393, 666, 787, 939, 7997, 53235, 55255, 55655, 57675, 506605, 1801081, 2215122, 3826283, 3866683, 5051505, 5226225, 5259525, 5297925, 5614165, 5679765, 53822835, 623010326, 954656459, 51717171715},
        {1, 2, 3, 4, 6, 88, 252, 282, 626, 676, 1221, 15751, 18881, 10088001, 10400401, 27711772, 30322303, 47633674, 65977956, 808656808, 831333138, 831868138, 836131638, 836181638, 2512882152, 2596886952, 2893553982, 6761551676, 12114741121, 12185058121},
        {1, 2, 3, 4, 5, 7, 55, 111, 141, 191, 343, 434, 777, 868, 1441, 7667, 7777, 22022, 39893, 74647, 168861, 808808, 909909, 1867681, 3097903, 4232324, 4265624, 4298924, 4516154, 4565654},
        {1, 2, 3, 4, 5, 6, 8, 121, 171, 242, 292, 16561, 65656, 2137312, 4602064, 6597956, 6958596, 9470749, 61255216, 230474032, 466828664, 485494584, 638828836, 657494756, 858474858, 25699499652, 40130703104, 45862226854, 61454945416, 64454545446},
        {1, 2, 3, 4, 5, 6, 7, 9, 121, 292, 333, 373, 414, 585, 3663, 8778, 13131, 13331, 26462, 26662, 30103, 30303, 207702, 628826, 660066, 1496941, 1935391, 1970791, 4198914, 55366355},
        {1, 2, 3, 4, 5, 6, 7, 8, 191, 282, 373, 464, 555, 646, 656, 6886, 25752, 27472, 42324, 50605, 626626, 1540451, 1713171, 1721271, 1828281, 1877781, 1885881, 2401042, 2434342, 2442442}
    };

public:
    long long kMirror(int k, int n) {
        return accumulate(ans[k - 2], ans[k - 2] + n, 0LL);
    }
};

二分查找类型总结

总结的动机是本次竞赛T3花费了很长时间,表明了对二分查找不熟悉。现在总结下二分查找的几种类型及其类型。

  • 可以证明 mid = (right + left)/2和mid = left + (right - left)/2结果是相同的,那么采用哪一种?
    • 采用后者,防止了数值溢出!

在递增序列中找到一个数

int binarySearch(int[] nums, int target) {
    int left = 0; 
    int right = nums.length - 1; // 注意

    while(left <= right) {
        int mid = left + (right - left) / 2;
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; // 注意
        else if (nums[mid] > target)
            right = mid - 1; // 注意
    }
    return -1;
}



  • 使用小于等于的原因:当while测试条件为left<=right时,搜索区间为[left,right];当while测试条件为left<right时,搜索区间为[left,right)(不包含right下标)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值