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

一、数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合。

举一个字符数组的例子,如图所示:

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

需要两点注意的是

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

正是因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

二、二分查找

1、力扣:704.二分查找

        二分法的第一种写法:定义 target 是在一个在左闭右闭的区间里,也就是[left, right]。

int left = 0; int right = nums.length - 1;

因为定义target在[left,right]区间,while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

        二分法的第二种写法:定义 target 是在一个在左闭右开的区间里,也就是[left, right)。

int left = 0; int right = nums.length;

        target 是在一个在左闭右开的区间里,也就是[left, right) ,

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  • if (nums[middle] > target) right 更新为 middle,if (nums[middle] < target) , left = middle + 1; // target 在右区间,在[middle + 1, right)中。
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int middle = (left + right) / 2;
            if (nums[middle] < target) {
                left = middle + 1;
            }else if (nums[middle] > target) {
                right = middle - 1;
            }else {
                return middle;
            }
        }
        return -1;
    }
}

三、双指针法

 2、力扣:27.移除元素

1. 暴力解法:两层for循环,内层for循环将target后面的元素向前覆盖。

        值得注意的是,因为下标i以后的数值都向前移动了一位,所以i也向前移动一位

class Solution {
    public int removeElement(int[] nums, int val) {
        int length = nums.length;
        for (int i = 0; i < length; i++) {
            if (nums[i] == val) {
                for (int j = i + 1; j < length; j++) {
                    nums[j - 1] = nums[j];
                }
                i--;// 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
                length--;
            }
        }
        return length;
    }
}

2.双指针法:通过一个快指针和慢指针在一个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];
            }
        }
        return slow;
    }
}

二、StringBuilder的使用

力扣:844.比较含退格的字符串z

        这题主要考察了对字符串的操作,这里主要总结一下StringBuilder 和StringBuffer与String的区别以及使用。

1、String与StringBuffer就是一个常量和变量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。

2、StringBuilder 与 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问),由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。删除字符串最后一个元素使用deleteCharAt(tsb.length()-1);

Java StringBuffer 和 StringBuilder 类 | 菜鸟教程

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

你可能感兴趣的:(代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素)