算法打卡Day1 | 数组篇-二分查找、 移除元素、移除元素

69 阅读2分钟

二分查找

力扣题目:leetcode.cn/problems/bi…

关键词:有序数组、数组中无重复元素

解题思路

  • 给定区间[left, right]
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        //给定区间[left, right]
        while (left <= right){
            int middle = (left + right) / 2;
            if(nums[middle] > target){
                right = middle - 1;
            }else if(nums[middle] < target){
                left = middle + 1;
            }else{
                return middle;
            }
        }
        return -1;
    }
}
  • 给定区间[left, right)
class Solution {
    public int search(int[] nums, int target) {
        //给定区间[left, right)
        int left = 0;
        int right = nums.length;
        while(left < right){
            int middle = (left + right) / 2;
            if(nums[middle] < target){
                left = middle + 1;
            }else if(nums[middle] > target){
                right = middle;
            }else{
                return middle;
            }
        }
        return -1;
    }
}

移除元素

力扣题目:leetcode.cn/problems/re…

关键词:数组、链表、字符串等,暴力解法时间复杂度高

解题思路

  • 本人写法

找一个先进先出的Queue,遇到指定的元素则将该元素位置存起来,每次遇到不一致的元素,将Queue中第一个位置赋值为该不一致的元素,并将该不一致元素的位置也存起来

class Solution {
    public int removeElement(int[] nums, int val) {
        Queue<Integer> queue = new ArrayDeque<>();
        int num = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == val){
                queue.add(i);
            }else{
                num++;
                if(!queue.isEmpty()){
                   int index = queue.peek(); 
                   if( i > index){
                    queue.poll();
                    nums[index] = nums[i];
                    queue.add(i);
                    }   
                }
                
            
            }
        }
        return num;
    }
}
  • 双指针解法

暴力解法使用两个for循环,如果遇到一样的,就把后面的值全都向前移

使用快慢指针,用一个for循环代替两个for循环

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法

class Solution {
    public int removeElement(int[] nums, int val) {
        //定义快慢指针 快指针去寻找新数组中的元素 慢指针指向新数组的位置
        int slow = 0;
        for(int fast = 0; fast < nums.length; fast++){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}

有序数组的平方

力扣题目:leetcode.cn/problems/sq…

关键词:非递减顺序 排序的整数数组

解题思路

最开始考虑如果用双指针,其中一个之中呢要么定位最大要么定位最小没每次遍历都和最大或最小作比较,但这不现实

这道题的关键在于非递减,所以平方之后,最大值只会在左右两边,不可能在中间,所以就可以两边分别比较

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] result = new int[nums.length];
        int k = result.length - 1;
        for(int i = 0,j = nums.length - 1;  i<=j; ){
            if(nums[i]*nums[i] < nums[j]*nums[j]){
                result[k--] = nums[j]*nums[j];
                j--;
            }else{
                result[k--] = nums[i]*nums[i];
                i++;
            }
        }
        return result;
    }
}