一个人的朝圣Leetcode打卡第一天
数组理论基础
分享一些常用的LeeCode刷题和数组相关的知识
数组的创建
int[] a = new int[9]; //默认每个值都为0
int[] intArray = { 1, 2, 3, 4, 5}; // 声明并且赋值
String[] bArray = {"a","b","c", "d", "e"};
String[][] str = new String[3][4]; // 生成二维数组
数组的遍历
// 使用下标
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
// 使用For-Each
for (String s : str){
System.out.print(s);
}
Arrays 工具类
// 1. 转化成List
List<T> asList(T ...a);
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
System.out.println(arrayList);
// 2. 打印
String toString(T[] a);
String intArrayString = Arrays.toString(intArray);
// 直接打印,则会打印出引用对象的Hash值
// [I@7150bd4d
// 3. 排序
sort(T[] a); // Sort the array
Arrays.sort(arr); // 默认从小到大排序
Arrays.sort(arr, 0, 3, (o1, o2) -> o2 - o1); //从大到小排序,只排序[0, 3)
// 4. 填充
int[] a = new int[5];
Arrays.fill(a, 1);
// 5. 克隆,复制
int[] a = new int[5];
int[] newA = Array.copyOf(a, 5);
// or
int[][] a = {{1}, {1,2}, {1,2,3}, {1,2,3,4}, {1,2,3,4,5}};
int[][] newa = a.clone(); // 5*5矩阵
LeetCode 704 二分查找
题目说明
在一个已经排序好的数列里面寻找target, 找到了返回对应的index, 否则返回-1.
代码说明
- int mid = (left + right) / 2 会返回数组中间的数值, 结果如果含有小数则会取整
- 跳出循环的条件为left > right, 当left = right是, 依然需要进入循环进行判断, 注意边界条件
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right){
int mid = (left + right) / 2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid -1;
}else{
left = mid + 1;
}
}
return -1;
}
}
LeetCode 27 移除元素
题目说明
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
题目难的地方在于数组储存的数据时连续内存的, 删除一个元素后需要将后面的元素往前移动, 时间复杂度可以达到 O(N^2)
代码说明
我的解决思路是使用双指针, 一个指向数组最左边, 一个指向数组最右边, 从左向右遍历数组, 当遇到需要删除的元素的时候, 将指针left 和 right 元素进行依次Swap (交换操作), 使得需要删除的元素都位于数组最后面.
需要注意一个Corner Case, 当遇到数组[3, 2, 2, 3] 时, 数组交换了之后仍然会保留需要删除的数, 所有加了一个Continue 操作避免了该现象的发生.
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length -1;
int temp;
while(left <= right){
if(nums[left] == val){
temp = nums[right];
nums[right] = nums[left];
nums[left] = temp;
right --;
continue;
}
left++;
}
return right + 1;
}
}
LeetCode 153. 寻找旋转排序数组中的最小值
题目说明
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题
代码说明
class Solution {
public int findMin(int[] nums) {
int left=0, right = nums.length -1;
while(left < right){
int mid = left + (right - left) /2;
if(nums[mid] < nums[right]){
right = mid;
}else{
left = mid + 1;
}
}
return nums[left];
}
}
模板总结
统一使用 while (left < right) :
寻找第一个满足XXX的位置:
int left = 0, right = nums.length - 1;
while (left < right) {
int middle = left + (right - left) / 2;
if (满足XXX) {
right = middle;
} else {
left = middle + 1;
}
}