刷题记录2 35. 搜索插入位置 | 34. 在排序数组中查找元素的第一个和最后一个位置 | 977. 有序数组的平方

题目链接:
35. 搜索插入位置 - https://leetcode.cn/problems/search-insert-position/description/
34. 在排序数组中查找元素的第一个和最后一个位置 - https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/
977. 有序数组的平方 - https://leetcode.cn/problems/squares-of-a-sorted-array/

35. 搜索插入位置

题目内容:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。

解题思路

二分法判断在不在数组里面,不在数组里面再判断和right的关系,确定位置

解题代码

class Solution {
    public int searchInsert(int[] nums, int target) {
        //先进行边界处理
        if(target > nums[nums.length - 1]){return nums.length;}
        if(target <= nums[0]){return 0;}

        //二分边界起点
        int left = 0;
        int right = nums.length;
        int mid;

        //判断在不在数组里面,跳出循环则表示没有找到
        while(left < right){
            mid = (left + right)/2;
            if(nums[mid] == target){
                return mid;
            }
            if(nums[mid] > target){
                right = mid;
                continue;
            }
            if(nums[mid] < target){
                left = mid + 1;
                continue;
            }
        }
        // 出来的时候只有一种情况 right <= left 
        if(nums[right] > target){
            return right;
        }
        return right + 1;
    }
}

注意点
1、出来以后使用right判断位置确定是不是边界。
     出来的时候有三种情况

  • right = 0 最左边 target < nums[0]
  • right = nums.length 最右边 target > nums[nums.length - 1]
  • 中间

一开始没有提前判断的时候,在跳出循环的时候它可能是左边界,可能是右边界,加一减一和taeget判断都会数组越界。
开始的边界判断,确定是否在边界。然后最后的判断是针对target在中间那个情况


更新

class Solution {
    public int searchInsert(int[] nums, int target) {
        for(int i = 0,len = nums.length; i < len;i++){
            if(nums[i] >= target){
                return i;
            }
        }
        return nums.length;
    }
}

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

题目内容:
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

解题思路

二分法判断在不在数组里面,在数组里面分别往两边去找边界

解题代码

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums.length <= 0 || target > nums[nums.length - 1] || target < nums[0]){
            return new int[]{-1,-1};
        }
        int left = 0;
        int right = nums.length;
        int mid;

        while(left < right){
            mid = (left + right)/2;
            if(nums[mid] == target){
                int beginIndex = mid;
                int endIndex = mid;
                while(beginIndex - 1 >= 0 && nums[beginIndex - 1] == target){beginIndex--;}
                while(endIndex + 1 < nums.length && nums[endIndex + 1] == target){endIndex++;}
                return new int[]{beginIndex,endIndex};
            }
            if(nums[mid] > target){
                right = mid; 
                continue;
            }
            if(nums[mid] < target){
                left = mid + 1;
                continue;
            }
        }
        return new int[]{-1,-1};
    }
}

注意点
1、找到边界以后要确定可不可以加一或减一,会不会越界

977. 有序数组的平方

题目内容:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

解题思路:
1、for循环,对数组里的元素直接开放使用Arrays.sort()排序
2、双指针法

第一种解题代码

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] ans = new int[nums.length];
        for (int i = 0; i < nums.length; ++i) {
            ans[i] = nums[i] * nums[i];
        }
        Arrays.sort(ans);
        return ans;
    }
}

双指针法

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        int index = nums.length - 1;
        int [] arrs = new int[nums.length];
        while(left < right){
            int temp1 = nums[left] * nums[left];
            int temp2 = nums[right] * nums[right];
            if(temp1 > temp2){
                left++;
                arrs[index--] =temp1;
                continue;
            }
            if(temp1 < temp2){
                right--;
                arrs[index--] =temp2;
                continue;
            }
            if(temp1 == temp2){
                right--;
                arrs[index--] =temp2;
                left++;
                arrs[index--] =temp1;
            }
        }
        if(index >= 0){
        arrs[index] = nums[left] * nums[left];}
        return arrs;
    }
}

补充数组相关知识

数组初始化的方式

1、动态初始化

初始化时由程序员指定数组的长度,由系统初始化每个数组元素的默认值。

int[] Arrs = new int[4];

2、静态初始化

初始化时由程序员显式指定每个数组元素的初始值,有系统决定数组的长度

int [] Arrs = new int[]{1,2,3};
int [] Arrs2 = {1,2,3};

List和数组相互转化的方式

List转数组

1、for 循环逐个设置
2、使用toArray()方法

//要转换的list集合
 List<String> testList = new ArrayList<String>(){{add("aa");add("bb");add("cc");}};
 //使用toArray(T[] a)方法
 String[] array2 = testList.toArray(new String[testList.size()]);

数组转List

1、for 循环逐个设置
2、使用asList()

String[] arr = new String[]{"aa","bb","cc"};
List<String> list = Arrays.asList(arrays);
posted @ 2024-03-20 22:07  虚拟式  阅读(17)  评论(0)    收藏  举报