本周题目来源于代码随想录,数组算法题,使用语言为java.
目录
一.二分查找
题目特征:
有序整型数组,查找目标值返回下标.
题解思路:
得益于数组自自身递增或递减与不重复的特性,利用双指针与中间值来实现对于数组区段的不断排查,避免了一个一个对比的时间损耗.
具体实现步骤细则:
首尾安排指针,以首尾的双指针为界限,中间值与目标值的大小确定所取范围,不断通过中间值刷新双指针的范围,直到双指针范围.
代码:
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;
}
}
注意事项:
双指针在使用时一定要明确好范围的开闭情况,否则在进行迭代时结束条件模糊不定.
二.移除元素
题目特征:
整型数组,返回删除目标值的数组(不创建新数组).
题解思路:
将查找与修改的操作分别给于两个指针,实现两步的同步进行.
具体实现步骤细则:
开头设置两个指针(查找与修改),查照指针依次往后检测是否符合目标值,修改指针将查照指针得到数字设置入原数组中,当查找遇见目标指时跳过继续检测下一个数字,从而实现对于目标值的删除.
代码:
class Solution {
public int removeElement(int[] nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
注意事项:
无
三.有序数组的平方
题目特征:
非递减整型数组,存在负数,返回由原数组数字平方构成的新数组,也按非递减排列.
题解思路:
主要问题在于数组左侧可能存在负数,其平方为正,故设置两端指针直接比较平方大小,然后存入新数组中.
具体实现步骤细则:
两端设置指针,比较平方后的大小,将更大的设置入新数组中.
代码:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] nums1 = new int[nums.length];
int l_n=0;
int r_n=nums.length-1;
int r_n1=nums.length-1;
while(l_n <= r_n){
if(nums[l_n]*nums[l_n] <= nums[r_n]*nums[r_n]){
nums1[r_n1] = nums[r_n]*nums[r_n];
r_n--;
} else if(nums[l_n]*nums[l_n] >= nums[r_n]*nums[r_n]){
nums1[r_n1] = nums[l_n]*nums[l_n];
l_n++;
}
r_n1--;
}
return nums1;
}}
注意事项:
无
四.长度最小的子数列
题目特征:
n个正整数的数组与目标值target,确定在数组中满足相邻数字相加大于等于目标值的最小子数组最小长度.
题解思路:
滑动窗口,双指针划定范围即窗口,在满足和的条件后记录个数值,刷新窗口,更新个数值并比较.
具体实现步骤细则:
开头设置两个指针为窗口的左边框和右边框,右边框依次右移,直到满足窗口内数字和大于等于目标值,确定目前窗口内数字个数,左框右移一位,重复右边框依次右移,再次满足检测数字个数与闪一次对比并留存较小的,直到右边框移到边界处.
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int l=0;
int sum=0;
int x=Integer.MAX_VALUE;
for(int r=0;r < nums.length;r++){
sum += nums[r];
while(sum >= target){
x=Math.min(x,r-l+1);
sum -= nums[l];
l++;
}
}
if(x == Integer.MAX_VALUE)
return 0;
return x;
}
}
注意事项:
双指针在使用时一定要明确好范围的开闭情况,否则在进行迭代时结束条件模糊不定.
五.螺旋矩阵II
题目特征:
设置出满足最值为目标数平方的螺旋数组.
题解思路:
将螺旋数组的设置过程分类,并且确保自始至终的计算法则不变.
具体实现步骤细则:
将螺旋数组的上侧右侧下侧左侧分为四个情况,使用迭代来依次计算更新数组,并留下一个记数器以确保及时停止.
代码:
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix=new int[n][n];
int mark=1;
int num=1;
while(mark <= n){
for(int i=mark-1;i <= n-mark;i++){
matrix[mark-1][i] = num;
num++;
}
for (int i=mark;i <= n-mark;i++){
matrix[i][n-mark] = num;
num++;
}
for (int i=n-mark-1;i >= mark;i--){
matrix[n-mark][i] = num;
num++;
}
for (int i=n-mark;i >= mark;i--){
matrix[i][mark-1] = num;
num++;
}
mark++;
}
return matrix;
}
}
注意事项:
一定要保证计算时四边的数字放置方法一致,特别是对于拐点处数字的确定,否则会导致迭代时数字放置出错.
综上
以上数组的算法题多利用迭代,擅用双指针能做到时间效率的提升。二分查找与滑动窗口这样的方法比较难想出来,也容易写错,需要练习.