一.數組
1.二分查找
给定一个 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]之间
思路:
1.定義左指針和右指針,mid=(left+right)/2,
2.用arr[mid]和元素n比較,如果相等返回下標mid
如果n大於arr[mid],n在右半區間,left=mid+1;
如果n小於arr[mid],n在左半區間,lright=mid-1;
答案:
package com.ts.programTest;
public class binarySearch {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9};
int key = 9;
int index = binarySearch(arr, key);
if (index == -1) {
System.out.println("Element not found");
} else {
System.out.println("Element found at index " + index);
}
}
public static int binarySearch(int[] arr, int key) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (arr[mid] == key) {
return mid;
} else if (arr[mid] < key) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
}
2.移除元素
给你一个数组 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。
你不需要考虑数组中超出新长度后面的元素。
思路: 定義一個快指針和一個慢指針,快指針for循環,如果nums[fast]不等於val,慢指針移動
package com.ts.programTest;
public class RemoveElement {
public static void main(String[] args) {
int[] nums = {0, 1, 2, 2, 3, 0, 4, 2};
int val = 2;
int len = removeElement(nums, val);
System.out.println(len);
}
private static 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;
}
}
3.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 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]
思路 :最大值一定位於兩端,采用雙指針
答案
package com.ts.programTest;
public class TheSquareOfAnOrderedArray {
public static void main(String[] args) {
int[] nums = {-4, -1, 0, 3, 10};
int[] result = orderSquare(nums);
for (int i : result) {
System.out.print(i + " ");
}
}
private static int[] orderSquare(int[] nums) {
int[] result = new int[nums.length];
int k = nums.length - 1;
for (int i = 0, j = nums.length - 1; i <= j; ) {
if (nums[i] * nums[i] > nums[j] * nums[j]) {
result[k--] = nums[i] * nums[i];
i++;
} else {
result[k--] = nums[j] * nums[j];
j--;
}
}
return result;
}
}
4.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
思路:
j指向子數組的末尾,i為子數組的頭部 。
sum累加,一旦sum的数值大于s,把子数组的长度更改为j-i+1(例如当j=1,i=0时,子数组的长度是 j-i+1=2)
sum的值减去nums[i]的值,i++
当j到达数组末尾时不在自增,代码在while中执行
代碼:
package com.ts.programTest;
public class theSmallestSubarray {
public static void main(String[] args) {
int s = 7;
int[] nums = {2, 3, 1, 2, 4, 3};
int result = findSmallestSubarray(s, nums);
System.out.println("最小子数组长度为:"+result);
}
private static int findSmallestSubarray(int s, int[] nums) {
int i = 0;
int sum = 0;
int result = nums.length;
for (int j = 0; j < nums.length; j++) {
sum += nums[j];
while (sum >= s) {
result = j-i+1;
sum -= nums[i];
i++;
}
}
return result;
}
}
5.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路:
螺旋矩阵:
n=3,3/2=1余1,表示从1开始顺时针绕一圈到达数字8,多出一个数字9
1 2 3
8 9 4
7 6 5
n=4,4/2=2,表示从1开始顺时针绕一圈到达12,再从13开始顺时针绕第二圈圈到达16
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
运用二位数组存矩阵
代码:
package com.ts.programTest;
public class spiralMatrixII {
public static void main(String[] args) {
int[][] matrix = getMatrix(4);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + "\t");
}
System.out.println();
}
}
public static int[][] getMatrix(int n) {
int[][] matrix = new int[n][n];
// 開始的所在行座標
int startX = 0;
// 開始的所在列座標
int startY = 0;
//矩陣裏面的數字
int count = 1;
//矩陣的行坐標和列坐標
int i;
int j;
//順時針繞一圈的次數
int loop = 1;
//n-size=每一圈的正方形長度
int size = 1;
while (loop <= n / 2) {
//頭部:例如第一圈的頭部是(0,0),(0,1),(0,2)分別存取數字1,2,3
for (j = startY; j < n - size; j++) {
matrix[startX][j] = count++;
}
//右側:例如第一圈的右側是(0,3),(1,3),(2,3)分別存取數字4,5,6
for (i = startX; i < n - size; i++) {
matrix[i][j] = count++;
}
//底部
for (; j > startY; j--) {
matrix[i][j] = count++;
}
//左側
for (; i > startX; i--) {
matrix[i][j] = count++;
}
startX++;
startY++;
loop++;
size++;
}
//如果n是奇數,説明一圈中多出了一個數字,將其放入矩陣中
if (n % 2 == 1) {
matrix[startX][startY] = count;
}
return matrix;
}
}