一维数组的内存地址是连续的
二维数组的内存地址 c++连续 Java不连续
移除元素
/**
* @Author:Sumschol
* @date: Created in 17:01 22/01/28
* @Descriptions:
* 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
*
* 不要使用额外的数组空间,你必须仅使用 $O(1)$ 额外空间并原地修改输入数组。
*
* 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
*
* 示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
*
* 示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
*
* 你不需要考虑数组中超出新长度后面的元素。
* @thinking:
* 快慢指针法
* 两指针同时向右移动,如果 快指针 = 目标值,慢指针不移动
* 如果 快指针 ≠ 目标值 【则用快指针内容覆盖慢指针内容】
* 下标 <=slow 的元素即为删除目标元素后的数组
*/
public class RemovingElements {
public static void main(String[] args) {
}
public static int removeElement(int[] nums, int val) {
int fast = 0, slow = 0;
for(int i = 1; i <= nums.length; i++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
二分搜索
/**
* @Author:Sumschol
* @date: Created in 16:38 22/01/28
* @Descriptions:
* 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
*
* 示例 1:
*
* 输入: nums = [-1,0,3,5,9,12], target = 9
* 输出: 4
* 解释: 9 出现在 nums 中并且下标为 4
* 示例 2:
*
* 输入: nums = [-1,0,3,5,9,12], target = 2
* 输出: -1
* 解释: 2 不存在 nums 中因此返回 -1
* 提示:
*
* 你可以假设 nums 中的所有元素是不重复的。
* n 将在 [1, 10000]之间。
* nums 的每个元素都将在 [-9999, 9999]之间。
* @thinking:
* 二分法前提:数组为有序数组,同时题目还强调数组中无重复元素
* 注意循环条件为 left <= right (left = right有意义)
*/
public class BinarySearch {
public static int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) / 2); //可防止left + right越界
if(nums[mid] < target){
left = mid + 1;
}
else if(nums[mid] > target){
right = mid - 1;
}
else {
return mid;
}
}
return -1;
}
}
/*
* 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
示例 4:
输入: nums = [1,3,5,6], target = 0
输出: 0
示例 5:
输入: nums = [1], target = 0
输出: 0
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为无重复元素的升序排列数组
-104 <= target <= 104
*
*/
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) / 2); //可防止left + right越界
if(nums[mid] < target){
left = mid + 1;
}
else if(nums[mid] > target){
right = mid - 1;
}
else {
return mid;
}
}
return left;
}
}
977. 有序数组的平方
/**
* @Author:Sumschol
* @date: Created in 20:52 22/01/28
* @Descriptions:
* 977. 有序数组的平方
*
* 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
*
* 示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
*
* 示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
* @thinking:
* 双指针法,从数组两端开始遍历,绝对值大的先进行计算并记入结果数组
* 时间复杂度为O(n)
*/
public class SortedSquares {
public static int[] sortedSquares(int[] nums) {
int[] ans = new int[nums.length];
int i = nums.length - 1;
int left = 0;
int right = nums.length - 1;
while(left != right){
if((nums[left] >= 0? nums[left]: -nums[left]) > (nums[right] >= 0? nums[right]: -nums[right])){
ans[i--] = nums[left] * nums[left];
left++;
}
else{
ans[i--] = nums[right] * nums[right];
right--;
}
}
ans[i] = nums[left] * nums[left];
return ans;
}
}
209. 长度最小的子数组
/**
* @Author:Sumschol
* @date: Created in 21:08 22/01/28
* @Descriptions:
*
* 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
*
* 示例:
*
* 输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
* @thinking:
* 滑动窗口:定义两个窗口边界指针,右指针不断右移,当 窗口和值 >= 目标值时,
* 只要 窗口和值 >= 目标值 就移动左指针(缩小窗口)
*/
public class Test {
public static void main(String[] args) {
int[] a = new int[3];
for (int i = 0; i < 3; i++) {
a[i] = i + 1;
}
minSubArrayLen(5,a);
}
public static int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int ans = Integer.MAX_VALUE; //便于后续比较判断
for(int left = 0,right = 0; right < nums.length; right++){
sum += nums[right]; //进入
while(sum >= target){
ans = ans >= right - left + 1? right - left + 1: ans;
sum -= nums[left++];
}
}
return ans == Integer.MAX_VALUE? 0: ans;
}
}
59.螺旋矩阵II
/**
* @Author:Sumschol
* @date: Created in 11:23 22/01/29
* @Descriptions:
* 给定一个正整数 n,生成一个包含 1 到 $n^2$ 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
*
* 示例:
*
* 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
* @thinking:
* 本题并不涉及到什么算法,就是模拟过程
* 坚持循环不变量原则
*/
public class Test {
public static void main(String[] args) {
generateMatrix(4);
}
public static int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
//起始位置
int startX = 0, startY = 0;
//循环次数
int loop = n / 2;
//填入数字
int content = 1;
//偏移量
int offSet = 1;
while(loop-- > 0){
int i = startX, j = startY;
//左上 -> 右上
for(; j <= (n - 1) - offSet; j++){
ans[startX][j] = content++;
}
//右上 -> 右下
for(; i <= (n - 1) - offSet; i++){
ans[i][j] = content++;
}
//右下 -> 左下
for(;j >= startY + 1; j--){
ans[i][j] = content++;
}
//左下 -> 左上
for(;i >= startX + 1; i--){
ans[i][j] = content++;
}
//开始位置
startX++;
startY++;
//偏移量
offSet += 1;
}
if(n % 2 == 1){ //处理中间块
int mid = n / 2;
ans[mid][mid] = content++;
}
return ans;
}
}