代码随想录算法训练营第1天 | 704.二分查找、27.移除元素、977.有序数组的平方

目录

704.二分查找

1.解题思路

2.遇到的问题

3.实现代码

4.题目总结

27.移除元素

1.解题思路

2.遇到的问题

3.实现代码

4.题目总结

977.有序数组的平方

1.解题思路

2.遇到的问题

3.实现代码

4.题目总结


704.二分查找

题目连接:704.二分查找

1.解题思路

数组有排序,我们先确定一个循环的进入条件和结束条件,该题存在两种情况,及右边界的选择:

左闭右闭:[left,right],我理解的是一种搜索区间,必须把所有下标都包括。

right=nums.length-1

循环进入条件:left<=right

right=mid-1

循环结束条件:left==right+1

左闭右开:[left,right)

right=nums.length-1

进入循环条件:left<right

right=mid

循环结束条件:left==right

2.遇到的问题

1.未考虑left+right会溢出的问题,可以使用mid=left+(right-left)/2

2.第一次做另left=mid++,此时的left是没有等于加1后的left,left还是原来的mid

3.实现代码
public static int search(int[] nums, int target) {     //左闭右闭
        int left=0;
        int right=nums.length-1;
        int mid=0;
        while (left<=right){
            mid=(left+right)/2;
            if (target>nums[mid]){
                left=mid+1;

            } else if (target<nums[mid]) {
                right=mid-1;

            }else {
                return mid;
            }
        }
        return -1;

    }
public static int search2(int[] nums,int target){    //左闭右开
        int left=0;
        int right=nums.length;
        while (left<right){
            int mid=(left+right)/2;

            if (nums[mid]==target){
                return mid;
            } else if (nums[mid]<target) {
                left=mid+1;
            } else if (nums[mid]>target) {
                right=mid;
            }
        }
        return -1;
    }
4.题目总结

二分查找中查找某一个数,处理好搜索区间即可快速解决该问题。

27.移除元素

题目链接:23.移除元素

1.解题思路

由于需要原地改变nums的元素,所以创建另外的数组就比较麻烦。

删除数组中的某个元素,不能真正的删除,只能从后往前覆盖,最后那个是什么无所谓,新的数组内存大小和原来的一样,只是有些语言对其进行了包装,计数器减了。

暴力解法

采用双循环,如果遇到等于val的就把后面的往前移一步将val覆盖。时间复杂度O(n^{2})

双指针解法

时间复杂度O(n),快指针用来获取新数组元素,及不需要的就不传给慢指针,慢指针用来获取新数组中需要更新的位置。

2.遇到的问题

1.暴力解法时内层循环中遇到不需要的元素i--,size同样也要--。

3.实现代码

暴力解法

class Solution {
    public static int removeElement(int[] nums, int val)
    {
        if (nums.length == 0) {
            return 0;
        }

        int size = nums.length;
        for (int i = 0; i < size; i++)
        {
            if (nums[i] == val)
            {
                for (int j = i + 1; j < size; j++)
                {
                    
                    nums[j - 1] = nums[j];// 数组整体左移
                }
                
                i--;// 由于整体左移,当前下标 i 也要左移,检查新的i下标元素
                
                size--;// 数组长度改变,外层size就不会越界检查不知道的元素
            }
        }
        return size;
    }
}

双指针解法

class Solution {
    public int removeElement(int[] nums, int val) {
             int slow=0;

        for (int i = 0; i < nums.length; i++) {
            if (nums[i]!=val){
                nums[slow]=nums[i];
                slow++;//在下一个位置搜集新元素
            }
        }
        return slow;
    }
}
4.题目总结

在处理数组和链表相关问题时,双指针技巧是经常用到的,双指针技巧主要分为两类:

左右指针快慢指针

本题使用到了快慢指针。

977.有序数组的平方

1.解题思路

1.利用 Arrays.sort(nums) (先平方再排序

先将数组中每个元素平方,注意平方是怎么平的,我是直接两个数相乘,再利用 Arrays.sort(nums) 升序排列数组。

2.双指针(题目本身是排了序,但是有负数)

一个指左边,一个指右边

2.遇到的问题

1.^是异或运算符,是一种位符。相同为0,不同为1。我的错误是误以为是平方了。

2.双指针时,注意不能int[] nums2 = nums,因为引用一样,改一个相当于改完了,应重新new一个。

3.实现代码

1.利用 Arrays.sort(nums) 

public class Pf {
    public int[] sortedSquares(int[] nums) {
        int slow=0;
        for (int i = 0; i < nums.length; i++) {
            nums[i]=nums[i]*nums[i];
        }
        Arrays.sort(nums);//是给nums排序,不用其他数组接收
        return nums;
    }
}

2.双指针

        int k = nums.length - 1;//新数组中获取元素的下标
        //int[] nums2 = nums;//这地方nums2与num指向同一个引用,nums改nums2也要改,nums2改nums也要改
        int[] nums2=new int[k+1];
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] < nums[right] * nums[right]) {
                nums2[k--] = nums[right] * nums[right];
                right--;
            } else {
                nums2[k--] = nums[left] * nums[left];
                left++;
            }
        }
        return nums2;

4.题目总结

注意引用变量,相等就等于引用了同一个地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值