Leetcode Weekly Contest 268(二分、贪心、进制转换)

题目链接: Leetcode Weekly Contest 268

1、2078. Two Furthest Houses With Different Colors

难度:Easy

双指针,从左往右和从右往左各扫描一遍。

代码:

class Solution {
    public int maxDistance(int[] colors) {
        int l=0,r=colors.length-1;
        int res=0;
        while(l<r){
            if(colors[l]!=colors[r]){
                res=r-l;
                break;
            }
            else{
                r--;
            }
        }
        l=0;
        r=colors.length-1;
        while(l<r){
            if(colors[l]!=colors[r]){
                res=Math.max(res,r-l);
                break;
            }
            else{
                l++;
            }
        }
        return res;
    }
}

2、2079. Watering Plants

难度:Medium

思路:

模拟即可。

代码:

class Solution {
    public int wateringPlants(int[] plants, int capacity) {
        int step=0;
        int i=-1;
        int full=capacity;
        while(i<plants.length-1){
            if(capacity>=plants[i+1]){
                capacity-=plants[i+1];
                i++;
                step++;
            }
            else{
                step+=(i-(-1));
                step+=(i+1-(-1));
                capacity=full-plants[i+1];
                i++;
            }
        }
        return step;
    }
}

3、2080. Range Frequency Queries

难度:Medium

思路:

暴力会超时,用二分法。

代码

class RangeFreqQuery {
    List<List<Integer>> list;
    public RangeFreqQuery(int[] arr) {
        list=new ArrayList<>();
        for(int i=0;i<=10000;i++){
            list.add(new ArrayList<>());
        }
        int n=arr.length;
        for(int i=0;i<n;i++){
            list.get(arr[i]).add(i);
        }
    }
    
    public int query(int left, int right, int value) {
        List<Integer> curr=list.get(value);
        int n=curr.size();
        if(n==0){
            return 0;
        }
        if(right<curr.get(0)||left>curr.get(n-1)){
            return 0;
        }
        int l=0,r=n-1;
        while(l<r){//寻找第一个大于等于left的元素的下标
            int mid=l+(r-l)/2;
            if(curr.get(mid)<left){
                l=mid+1;
            }
            else{
                r=mid;
            }
        }
        int i=0,j=n-1;
        while(i<j){//寻找最后一个小于等于right的元素的下标
            int mid=i+(j-i+1)/2;
            if(curr.get(mid)>right){
                j=mid-1;
            }
            else{
                i=mid;
            }
        }
        return i-l+1;
    }
}

/**
 * Your RangeFreqQuery object will be instantiated and called as such:
 * RangeFreqQuery obj = new RangeFreqQuery(arr);
 * int param_1 = obj.query(left,right,value);
 */

4、 2081. Sum of k-Mirror Numbers

难度:Hard

思路

参考高赞回答,用三个函数讲此题进行拆解,化繁为简。

代码

class Solution {
    public long kMirror(int k, int n) {
        long num=0;
        long sum=0;
        while(n>0){
            num=nextPalindrome(num);
            String s=decToK(num,k);
            if(isPalindrome(s)){
                sum+=num;
                n--;
            }
        }
        return sum;
    }
    public long nextPalindrome(long num){
        //返回比str大的下一个回文数
        String str=Long.toString(num);
        char[] s=str.toCharArray();
        int size=s.length;
        for(int i=size/2;i>=0;i--){
            if(s[i]!='9'){
                s[i]++;
                if(size-1-i!=i){//size-1-i和i对称
                    s[size-1-i]++;//如果不是同一个位置,对称位置上的元素也加1
                }
                for(int j=i+1;j<=size/2;j++){
                    //如129921,下一个回文数应该是120031
                    s[j]='0';
                    s[size-1-j]='0';
                }
                return Long.parseLong(new String(s));
            }
        }
        //如果每一位上都是9,如9999,下一个回文数应该是10001
        long ans=1;
        while(size>0){
            ans*=10;
            size--;
        }
        ans+=1;
        return ans;
    }
    
    public boolean isPalindrome(String str){
        char[] s=str.toCharArray();
        int l=0,r=s.length-1;
        while(l<r){
            if(s[l]!=s[r]){
                return false;
            }
            l++;
            r--;
        }
        return true;
    }
    
    public String decToK(long num,int k){
        //十进制转k进制
        StringBuilder sb=new StringBuilder();
        while(num!=0){
            sb.append((char)(num%k+'0'));//注意这里要进行类型转化char要加括号变成(char)!!!
            //3+'0'=3+48('0'的ASIC码)=51
            num/=k;
        }
        return sb.reverse().toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值