代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

本文介绍了数组理论基础,包括二分查找算法实现及其应用,以及如何在原地移除元素并保持数组长度不变。还涉及到了使用快慢指针解决删除重复项和移动零等问题。
摘要由CSDN通过智能技术生成

代码随想录算法训练营

今日任务
数组理论基础,704. 二分查找,27. 移除元素



数组理论基础

文章链接:

https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html


704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

class Solution {
    public int search(int[] nums, int target) {
        int len=nums.length;
        int low=0;
        int high=len-1;
        int mid=(low+high)/2;
        int pos=-1;
        while(low<=high){
            if(nums[mid]==target){
            	//找到咯
                pos=mid;
                break;
            }else if(nums[mid]<target){
                //向右
                low=mid+1;
            }else{
                //向左
                high=mid-1;
            }
            mid=(low+high)/2;
        }
        return pos;
    }
}


27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

//暴力解法
class Solution {
    public int removeElement(int[] nums, int val) {
        int start=0;
        int end=nums.length-1;
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]==val){
                for(int j = end; j>i; j--){
                    if(nums[j]!=val){
                        //交换位置
                        int temp=nums[j];
                        nums[j]=nums[i];
                        nums[i]=temp;
                        end=j;
                        //回退一位i,保证start
                        i=i-1;
                        break;
                    }
                }
            }else{
                start=i+1;
            }
        }
        return start;
    }
}

//双指针法
class Solution {
    public int removeElement(int[] nums, int val) {
        //定义一个快指针和慢指针
        //如果当前的nums[i]!=val,快指针的nums值赋给慢指针对应的nums值,两个指针都+1
        //如果当前的nums[i]==val,快指针仍+1,而慢指针不动
        int slowIndex=0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if(nums[fastIndex]!=val){
                nums[slowIndex]=nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}

相关题目推荐

26.删除排序数组中的重复项
考虑篇幅原因就懒得粘贴题目内容了,都是力扣上的,菜菜加油//!

//暴力解法
//有一点点的桶排序的思想吗hhh
class Solution {
    public int removeDuplicates(int[] nums) {
        int[] bucket=new int[20005];
        for (int i = 0; i < nums.length; i++) {
            bucket[nums[i]+10000]++;
        }
        int j=0;
        for (int i = 0; i < bucket.length; i++) {
            if(bucket[i]!=0){
                nums[j]=i-10000;
                j++;
            }
        }
        return j;
    }
}
//快慢指针方法
class Solution {
    public int removeDuplicates(int[] nums) {
        int slowIndex=0;
        int val=nums[slowIndex];
        for (int fastIndex = 1; fastIndex < nums.length; fastIndex++) {
            if(val<nums[slowIndex]){
                val=nums[slowIndex];
            }
            if(nums[fastIndex]!=val){
                slowIndex++;
                nums[slowIndex]=nums[fastIndex];
            }
        }
        return slowIndex+1;
    }
}

283.移动零

class Solution {
    public void moveZeroes(int[] nums) {
        //快慢指针
        int slowIndex=0;
        int val=0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if(nums[fastIndex]!=val){
                nums[slowIndex]=nums[fastIndex];
                slowIndex++;
            }
        }
        for (int i = slowIndex; i < nums.length; i++) {
            nums[i]=0;
        }
    }
}

844.比较含退格的字符串

//无事,做出来就行哈哈哈
class Solution {
    public boolean backspaceCompare(String s, String t) {
        s=doubleIndex(s);
        t=doubleIndex(t);
        if(s.equals(t)){
            return true;
        }else{
            return false;
        }
    }
    public static String doubleIndex(String s) {
        //从后向前进行快慢指针
        int slowIndex = s.length()-1;
        char val = '#';
        char newchar='0';
        char[] chars = s.toCharArray();
        for (int fastIndex = chars.length-1; fastIndex >= 0; fastIndex--) {
            if(chars[slowIndex]==val&&chars[fastIndex]!=val&&fastIndex<=slowIndex){
                chars[fastIndex]=newchar;
                for(int j=slowIndex-1;j>=0;j--){
                    if(chars[j]==val){
                        slowIndex=j;
                        break;
                    }else if(j==0){
                        slowIndex=j;
                    }
                }

            }else if(chars[slowIndex]!=val&&slowIndex!=0){
                slowIndex--;
            }
        }
        String str="";
        for (int i = 0; i < chars.length; i++) {
            if(chars[i]!=val&&chars[i]!=newchar){
                str=str+chars[i];
            }
        }
        return str;
    }
}

977.有序数组的平方
放在day2的作业里了

↓补完了

35.搜索插入位置

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        int mid=(left+right)/2;
        int flag=0;
        while(left<=right){
            if(nums[mid]==target){
                flag=1;
                break;
            }else if(nums[mid]<target){
                //大,在右边
                left=mid+1;
            }else{
                //在左边
                right=mid-1;
            }
            mid=(left+right)/2;
        }
        if(flag!=1){
            if(target>nums[mid]){
                return mid+1;
            }else{
                return mid;
            }
        }else{
            return mid;
        }
    }
}

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

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums.length==0||(nums.length==1&&nums[0]!=target)){
            int[] result={-1,-1};
            return result;
        }
        int low=0;
        int high=nums.length-1;
        //使用二分法找到一个后,再细化分,找左边和右边的
        //先找左边?
        int left=-1;
        int right=-1;
        int mid=pos(low,high,nums,target);
        if(nums[mid]!=target){
                //找不到
                int[] result={-1,-1};
                return result;
        }
        while(true){
            //左边
            if((mid==0&&nums[mid]==target)||(nums[mid-1]!=target&&nums[mid]==target)){
                left=mid;
                break;
            }else{
                high=mid-1;
                mid=pos(low,high,nums,target);
                if(nums[mid]<target){
                    low=mid+1;
                }else if(nums[mid]>target){
                    high=mid-1;
                }else if((mid==0&&nums[mid]==target)||(nums[mid-1]!=target&&nums[mid]==target)){
                    left=mid;
                    break;
                }
            }
        }
        //寻找右边
        low=0;
        high=nums.length-1;
        mid=pos(low,high,nums,target);
        while(true){
            if((mid==nums.length-1&&nums[mid]==target)||(nums[mid]==target&&nums[mid+1]!=target)){
                right=mid;
                break;
            }else{
                low=mid+1;
                mid=pos(low,high,nums,target);
                if(nums[mid]<target){
                    low=mid+1;
                }else if(nums[mid]>target){
                    high=mid-1;
                }else if((mid==nums.length-1&&nums[mid]==target)||(nums[mid]==target&&nums[mid+1]!=target)){
                    right=mid;
                    break;
                }
            }
        }
        int[] result={left,right};
        return result;
    }
    public int pos(int low,int high,int[] nums,int target){
        int mid=(low+high)/2;
        while(low<=high){
            if(nums[mid]==target){
                break;
            }else if(nums[mid]<target){
                low=mid+1;
            }else if(nums[mid]>target){
                high=mid-1;
            }
            mid=(low+high)/2;
        }
        return mid;
    }
}

69.x 的平方根

//卑鄙的使用计算器来缩小范围哈哈哈
class Solution {
    public int mySqrt(int x) {
        int low=1;
        int high=x;
        if(x>46340){
            high=46340;
        }
        int mid=(low+high)/2;
        while(low<=high){
            if(mid*mid==x){
                break;
            }else if(mid*mid<x){
                low=mid+1;
            }else if(mid*mid>x){
                high=mid-1;
            }
            mid=(low+high)/2;
        }
        return mid;
    }
}

367.有效的完全平方数

class Solution {
    public boolean isPerfectSquare(int num) {
        boolean result=false;
        int low=1;
        int high=num;
        if(num>46340){
            high=46340;
        }
        int mid=(low+high)/2;
        while(low<=high){
            if(mid*mid==num){
                break;
            }else if(mid*mid<num){
                low=mid+1;
            }else if(mid*mid>num){
                high=mid-1;
            }
            mid=(low+high)/2;
        }
        if(mid*mid==num){
            result=true;
        }
        return result;
    }
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值