概要
数组理论基础
- 数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
- 数组的元素是不能删的,只能覆盖。
注意点
二维数组
不同编程语言的内存管理是不一样的。
以C++为例,在C++中二维数组是连续分布的。
C++二维数组地址
例:
0x7ffee4065820 0x7ffee4065824 0x7ffee4065828
0x7ffee406582c 0x7ffee4065830 0x7ffee4065834
注意地址为16进制,可以看出二维数组地址是连续一条线的。
但是Java是没有指针的,同时也不对程序员暴露其元素的地址,寻址操作完全交给虚拟机。
注意地址为16进制,可以看出二维数组地址是连续一条线的。
Java二维数组地址
例:
[I@7852e922
[I@4e25154f
[I@70dea4e
[I@5c647e05
二维数组的每一行头结点的地址是没有规则的,更谈不上连续。
所以Java的二维数组可能是如下排列的方式:
704. 二分查找
题目链接
题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
思路
这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,满足如上条件的时候,要想一想是不是可以用二分法了。
二分法要注意区间
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。
实现代码
左闭右闭区间
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return -1;
}
}
左闭右开区间
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length;
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid;
}
return -1;
}
}
27. 移除元素
题目链接
题目描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路
数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
实现代码
暴力解法
public class Solution {
public int removeElement(int[] nums, int val) {
int count = 0;
for (int i = 0; i < nums.length - count;) {
int last = nums.length - count;
if (nums[i] == val) {
if (nums[last - 1] == val) {
count++;
} else {
int temp = nums[i];
nums[i] = nums[last - 1];
nums[last - 1] = temp;
count++;
i++;
}
} else {
i++;
}
}
return nums.length - count;
}
}
双指针(快慢指针)
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;
}
}