数组理论基础
文档讲解:代码随想录
视频讲解:数组理论B站
目标:了解一下数组基础,以及数组的内存空间地址,数组也没那么简单。
状态:基本了解,主要细节,数组是存放在连续内存空间上的相同类型数据的集合,是通过下表索引进行访问,下标都是从0开始,内存空间的地址是连续的。
java的数组排列方式不太一样,因为java没有指针,所以寻址操作是交给虚拟机的,示意图如下:
704 . 二分查找
文档讲解:代码随想录
视频讲解:手把手带你撕出正确的二分法
状态:有思想,写代码时候遇到java语法问题(太久没写Java了)
目标:先把 704写熟练,要熟悉 根据 左闭右开,左闭右闭 两种区间规则 写出来的二分法
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left<=right){
// int index = left + ((right - left) >> 1);
int index = left + ((right-left)/2);
if(nums[index]>target){
right = index - 1 ;
}
else if(nums[index]<target){
left = index + 1;
}
else if (nums[index]==target){
return index;
}
}
return -1;
}
}
其中一个语法细节{ (right - left) >> 1 },>>相当于除以2然后取整。参考连接:Java 中的位移运算符 >> , << , >>>
27. 移除元素
题目链接:27. 移除元素
文档讲解:代码随想录
视频讲解:LeetCode:27. 移除元素
状态:第一遍看题目有点懵逼不知道要干嘛,然后看解析知道了思想,了解了两种写法,分别是双循环暴力破解,双指针。然后就是进阶的左右双指针。
目标:暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握
//暴力破解法
class Solution {
public int removeElement(int[] nums, int val) {
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--; // 此时数组的大小-1
}
}
return size;
}
}
//双指针
class Solution {
public int removeElement(int[] nums, int val) {
int fast,slow = 0;
// System.out.println("slow:"+slow);
for(fast = 0;fast<nums.length;fast++){
if(nums[fast]!=val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
//左右指针比较巧妙的解法
class Solution {
public int removeElement(int[] nums, int val) {
int j = nums.length - 1;
for (int i = 0; i <= j; i++) {
if (nums[i] == val) {
swap(nums, i--, j--);
}
}
return j + 1;
}
void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
执行过程:
对于这个例子 [0,1,2,2,3,0,4,2] 和 val = 2:
初始化 j = nums.length - 1 = 7,i = 0。
进入循环,i = 0,j = 7,nums[i] = 0,不等于 val,所以 i 增加 1。
- i = 1,j = 7,nums[i] = 1,不等于 val,所以 i 增加 1。
- i = 2,j = 7,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,2,2,3,0,4,2],i = 1,j = 6。
- i = 1,j = 6,因为 i 减少了 1,所以我们回到 nums[1],它等于 1,不等于 val,所以 i 增加 1。
- i = 2,j = 6,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,4,2,3,0,2,2],i = 1,j = 5。
- i = 1,j = 5,因为 i 减少了 1,所以我们回到 nums[1],它等于 1,不等于 val,所以 i 增加 1。
- i = 2,j = 5,nums[i] = 4,不等于 val,所以 i 增加 1。
- i = 3,j = 5,nums[i] = 2,等于 val,所以交换 nums[i] 和 nums[j],然后 i 和 j 都减 1。现在数组变为 [0,1,4,0,3,2,2,2],i = 2,j = 4。
- i = 2,j = 4,因为 i 减少了 1,所以我们回到 nums[2],它等于 4,不等于 val,所以 i 增加 1。
- i = 3,j = 4,nums[i] = 0,不等于 val,所以 i 增加 1。
- i = 4,j = 4,nums[i] = 3,不等于 val,所以 i 增加 1。
- 现在 i = 5,j = 4,i > j,所以退出循环。
- 返回 j + 1 = 5,这是新的数组长度。
所以,最后的结果是数组变为 [0,1,4,0,3,2,2,2],新的数组长度为 5。注意,数组的后三个元素是无效的,因为它们已经被移除