977. 有序数组的平方二分法使用前提:有序数组
二分法:分别可以利用[a,b]或[a,b)来处理边界
方法一:二分法(nums[mid]==target应与其他情况合并,否则会超出时间)
class Solution {
public int[] searchRange(int[] nums, int target) {
int len=nums.length;
if(len==0){
return new int[]{-1,-1};
}
int firstPosition=findFirstPosition(nums,target);
if(firstPosition==-1){
return new int[]{-1,-1};
}
int lastPosition=findLastPosition(nums,target);
return new int[]{firstPosition,lastPosition};
}
private int findFirstPosition(int[] nums,int target){
int left=0;
int right=nums.length-1;
while(left<=right){
int mid=left+((right-left)/2);
if(nums[mid]<target){
//下一轮搜索区间是[mid+1,right]
left=mid+1;
}else if (nums[mid] >= target) {
//下一轮搜索区间是[left,mid-1]
right=mid-1;
}
}
if(left>=nums.length||nums[left]!=target){
return -1;
}
return left;
}
private int findLastPosition(int[] nums,int target){
int left=0;
int right=nums.length-1;
while(left<=right){
int mid=left+((right-left)/2);
if(nums[mid]<=target){
//下一轮搜索区间是[mid+1,right]
left=mid+1;
}else if (nums[mid] > target) {
//下一轮搜索区间是[left,mid-1]
right=mid-1;
}
}
if (right<0||nums[right]!=target) {
return -1;
}
return right;
}
}
方法二:双指针
public int[] searchRange(int[] nums, int target) {
int[] res=new int[]{-1,-1};
if(nums.length<1) return res;
int i=0;
int j=nums.length-1;
while(i<=j&&nums[i]<target) i++;
while(i<=j&&nums[j]>target) j--;
if(i>j||nums[i]!=target||nums[j]!=target) return res;
res[0]=i;
res[1]=j;
return res;
}
方法三:暴力查找,从左边找初始位置,从右边查找结束位置。
public int[] searchRange(int[] nums, int target) {
if(nums.length==0) return new int[] {-1,-1};
int left = searchLeft(nums,target);
int right = searchRight(nums,target);
if (left == -1 || right == -1) {
return new int[] {-1,-1};
}
return new int[] {left,right};
}
private int searchRight(int[] nums, int target) {
for (int i = nums.length - 1; i >= 0; i--) {
if (nums[i] == target) {
return i;
}
}
return -1;
}
public int searchLeft(int[] nums,int target) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
return i;
}
}
return -1;
}
方法1:暴力;方法2:双指针
int size=nums.length; for(int i=0;i<size;i++){ if(nums[i]==val){ for(int j=i+1;j<size;j++){ nums[j-1]=nums[j]; } i--; size--; } } return size;
int n = nums.length; int left = 0; for (int right = 0; right < n; right++) { if (nums[right] != val) { nums[left] = nums[right]; left++; } } return left;
209. 长度最小的子数组(滑动窗口)
public int[][] generateMatrix(int n) {
int l=0,r=n-1,u=0,d=n-1;
int[][] matrix=new int[n][n];
int cum=1,end=n*n;
while(true){
for(int i=l;i<=r;i++) matrix[u][i]=cum++;
if(++u>d) break;
for(int i=u;i<=d;i++) matrix[i][r]=cum++;
if(--r<l) break;
for(int i=r;i>=l;i--) matrix[d][i]=cum++;
if(--d<u) break;
for(int i=d;i>=u;i--) matrix[i][l]=cum++;
if(++l>r) break;
}
return matrix;
}
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res=new LinkedList<>();
if(matrix.length==0) return res;
int u=0,d=matrix.length-1,l=0,r=matrix[0].length-1;
while(true){
for(int i=l;i<=r;i++) res.add(matrix[u][i]);
if(++u>d) break;
for(int i=u;i<=d;i++) res.add(matrix[i][r]);
if(--r<l) break;
for(int i=r;i>=l;i--) res.add(matrix[d][i]);
if(--d<u) break;
for(int i=d;i>=u;i--) res.add(matrix[i][l]);
if(++l>r) break;
}
return res;
}
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0) return new int[0];
int l = 0, r = matrix[0].length - 1, u = 0, d = matrix.length - 1, x = 0;
int[] res = new int[(r + 1) * (d + 1)];
while(true) {
for(int i = l; i <= r; i++) res[x++] = matrix[u][i]; // left to right.
if(++u > d) break;
for(int i = u; i <= d; i++) res[x++] = matrix[i][r]; // top to bottom.
if(l > --r) break;
for(int i = r; i >= l; i--) res[x++] = matrix[d][i]; // right to left.
if(u > --d) break;
for(int i = d; i >= u; i--) res[x++] = matrix[i][l]; // bottom to top.
if(++l > r) break;
}
return res;
}