数组介绍
数组(array)是一种线性数据结构,其将相同类型的元素存储在连续的内存空间中。我们将元素在数组中的位置称为该元素的索引(index),
数组存储在连续的内存空间内,且元素类型相同。这种做法包含丰富的先验信息,系统可以利用这些信息来优化数据结构的操作效率。
- 空间效率高:数组为数据分配了连续的内存块,无须额外的结构开销。
- 支持随机访问:数组允许在 O(1) 时间内访问任何元素。(
索引本质上是内存地址的偏移量。首个元素的地址偏移量是 0 ,因此它的索引为 0 是合理的。在数组中访问元素非常高效,我们可以在 O(1) 时间内随机访问数组中的任意一个元素)
- 缓存局部性:当访问数组元素时,计算机不仅会加载它,还会缓存其周围的其他数据,从而借助高速缓存来提升后续操作的执行速度。
连续空间存储是一把双刃剑,其存在以下局限性。
- 插入与删除效率低:当数组中元素较多时,插入与删除操作需要移动大量的元素。
- 长度不可变:数组在初始化后长度就固定了,扩容数组需要将所有数据复制到新数组,开销很大。
- 空间浪费:如果数组分配的大小超过实际所需,那么多余的空间就被浪费了。
704. 二分查找:leetcode地址
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
解题:
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
while(left <= right){
int middle = left + ((right - left) >> 1);
if(nums[middle]>target){
right=middle-1; }
else if (nums[middle]<target){
left=middle+1;}
else {
return middle;
}
}
return -1;
}
}
注:加减运算都优先于移位运算,所以我自己写的时候少加个括号,导致错误
int mid = left + ((right - left) >> 1);
27. 移除元素leetcode地址
暴搜两层for
class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
for(int i = 0; i <=size - 1; i++ ){
if(nums[i] == val){
for(int j = i + 1; j<=size - 1; j++){
nums[j - 1] = nums[j];
}
i--;
size--;;
}
}
return size;
}
}
双指针:快指针寻找目标数,慢指针标记目标位,将快指针位置的数赋给慢指针位置,慢指针++
class Solution {
public int removeElement(int[] nums, int val) {
int solwIndex = 0;
for(int firstIndex = 0;firstIndex < nums.length;firstIndex++){
if(nums[firstIndex] != val){
nums[solwIndex] = nums[firstIndex];
solwIndex++;
}
}
return solwIndex;
}
}
977.有序数组的平方leetcode地址
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int index = nums.length - 1;
int[] result = new int[nums.length];
while(left <= right){
if(nums[left]*nums[left] < nums[right] * nums[right] ){
result[index] = nums[right] * nums[right];
index--;
right--;
}
else{
result[index] = nums[left]*nums[left];
index--;
left++;}
}
return result;
}
}
没想到思路,想到是双指针问题,但是快慢指针做着做着成冒泡了,看来题解平方之后最大值只能在两头,所以在两头加双指针往中间移动
做题:3h
博客: 0.5h