hot100:数组——34、46

34. 在排序数组中查找元素的第一个和最后一个位置

思路:使用两次二分法,第一次查找target出现的结尾位置,第二次查找target出现的开头位置。
这道题先看第一个二分法,是先通过二分查找target出现的第一个位置:如果mid元素大于等于target,就将范围缩小到mid左边;
第二个二分法查找的是target出现的末尾位置,:如果mid元素小于等于target,就将范围缩小到mid右边;

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums.length==0) return new int[]{-1,-1};
        int l=0,r=nums.length-1,mid=0;
        while(l<r){
            mid=(l+r)/2;
            if(nums[mid]>=target){
                r=mid;
            }else{
                l=mid+1;
            }
        }
        if(nums[l]!=target) return new int[]{-1,-1};
        int L=l;
        l=0;
        r=nums.length-1;
        while(l<r){
            mid=(l+r+1)/2;
            if(nums[mid]<=target){
                l=mid;
            }else{
                r=mid-1;
            }
        }
        return new int[]{L,r};
    }
}

这里有两个模板可以参考一下:

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = (l + r)/2;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = ( l + r + 1 ) /2;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

两个的区别就是mid的计算方式:到底用不用+1:因为如果左边界l更新为l=mid,此时mid的取值就应为mid=(l+r+1)/2。根据代码,当右边界r=l+1时,此时mid=(l+l+1)/2,下取整,mid仍为l,左边界再次更新为l=mid=l,相当于没有变化,while循环就会陷入死循环。

这是因为没有将mid元素单独设置判断条件的原因,如果有if(nums[mid]==target)就不用考虑mid=l的问题,因为l,r只能是mid+1和mid-1,不会等于mid

46. 全排列

改了又改

class Solution {
    List<List<Integer>> res=new LinkedList<>();
    LinkedList<Integer> path=new LinkedList<>();//这里要注意,path在开始声明时就要是LinkedList
    //不然不能使用下面的removeLast方法
    boolean[] used;
    public List<List<Integer>> permute(int[] nums) {
        used=new boolean[nums.length];
        if(nums.length==0) return res;
        permuteHelper(nums);
        return res;
    }
    public void permuteHelper(int[] nums){
        if(path.size()==nums.length){//LinkedList的元素个数只能使用size,不能使用length属性
            res.add(new LinkedList<>(path));//这里的意思是,新建一个LinkedList,初始化是path中的元素,且和path顺序一致
            //如果直接写成res.add(path),结果不对
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(used[i]){
                continue;
            }
            used[i]=true;
            path.add(nums[i]);
            permuteHelper(nums);
            path.removeLast();
            used[i]=false;
        }
    }
}

目前认为,代码中需要res.add(new LinkedList<>(path))的原因是,和多维数组一样,虽然已经有res这个集合,但是集合中各个元素还没有初始化,所以需要先new

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值