2021-03-17力扣刷题

数组+二分法

编号35
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:

输入: [1,3,5,6], 5
输出: 2
示例 2:

输入: [1,3,5,6], 2
输出: 1
示例 3:

输入: [1,3,5,6], 7
输出: 4
示例 4:

输入: [1,3,5,6], 0
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-insert-position
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package test;

import java.util.Scanner;

//编号35
public class Main {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			a[i]=scanner.nextInt();
		}
		int target = scanner.nextInt();
		Main main = new Main();
		System.out.println(main.searchInsert(a, target));
	}
	public int searchInsert(int[] nums, int target) {
    
    
		   int l = 0;
	       int r = nums.length-1;
	       int mid = 0;
	       while(l<=r) {
    
    //不变量target在左闭右闭区间
	    	   mid = l+(r-l)/2;
	    	   if(nums[mid]>target) {
    
    
	    		   r=mid-1;
	    	   }else if (nums[mid]<target) {
    
    
	    		   l=mid+1;
	    	   }else {
    
    
	    		   return mid;
	    	   }
	      }
	      /**
	       * target是数组某个元素,所以return mid
	       * target在所有元素之前,跳出循环后left,right=>0,-1,所以return r+1
	       * target在所有元素之后,跳出循环后left,right=>right,left,所以return r+1
	       * target在插入数组之间,跳出循环后left,right=>right,left,所以return r+1
	       * 
	       */
	      return r+1;
    }
}

原地操作数组

编号27
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

提示:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法1:排序

package test;

import java.util.Arrays;
import java.util.Scanner;

public class Main1 {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			a[i]=scanner.nextInt();
		}
		int val = scanner.nextInt();
		Main1 main = new Main1();
		System.out.println(main.removeElement(a, val));
	}
	 public int removeElement(int[] nums, int val) {
    
    
		 int count=0;
		 for (int i = 0; i < nums.length; i++) {
    
    
			if(nums[i]==val) {
    
    
				count++;
				nums[i]=Integer.MAX_VALUE;
			}
		}
		Arrays.sort(nums);
		return nums.length-count;
	 }
}

解法2:双指针

package test;

import java.util.Arrays;
import java.util.Scanner;

public class Main1 {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			a[i]=scanner.nextInt();
		}
		int val = scanner.nextInt();
		Main1 main = new Main1();
		System.out.println(main.removeElement2(a, val));
	}
	public int removeElement2(int[] nums, int val) {
    
    
		 int slowIndex = 0;//指向非目标值元素
		 for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
    
    
			if(val!=nums[fastIndex]) {
    
    
				nums[slowIndex++]=nums[fastIndex];
			}
		 }
		 return slowIndex;
	 }
}

长度最小的子数组

编号209
给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:

输入:target = 4, nums = [1,4,4]
输出:1
示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105

进阶:

如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

暴力法,双重循环

package lk2021_03_17;

import java.util.Scanner;

//编号209
public class Main {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			a[i]=scanner.nextInt();
		}
		int target = scanner.nextInt();
		Main main = new Main();
		System.out.println(main.minSubArrayLen(target, a));
	}
	public int minSubArrayLen(int target, int[] nums) {
    
    
		int res=Integer.MAX_VALUE;
		for (int i = 0; i < nums.length; i++) {
    
    
			int sum=0;
			int count=0;
			for (int j = i; j < nums.length; j++) {
    
    
				sum+=nums[j];
				if(sum>=target) {
    
    
					count=j-i+1;
					res=Math.min(res, count);
					break;
				}
				count++;
			}			
		}
		return res==Integer.MAX_VALUE?0:res;
    }
}

解法2,滑动窗口

package lk2021_03_17;

import java.util.Scanner;

public class Main2 {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n=scanner.nextInt();
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			a[i]=scanner.nextInt();
		}
		int target = scanner.nextInt();
		Main2 main = new Main2();
		System.out.println(main.minSubArrayLen(target, a));
	}
	public int minSubArrayLen(int target, int[] nums) {
    
    
		int res = Integer.MAX_VALUE;
		int sum=0;//窗口总和
		int i=0;//窗口起始位置
		for (int j = 0; j < nums.length; j++) {
    
    
			sum+=nums[j];
			while(sum>=target) {
    
    
				int len=j-i+1;//子序列长度
				res=res>len?len:res;//取较小值
				sum-=nums[i++];//起始位置变化
			}
		}
		return res==Integer.MAX_VALUE?0:res;//对Integer.MAX_VALUE结果处理
	}
}

螺旋矩阵II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:
在这里插入图片描述

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:

输入:n = 1
输出:[[1]]

提示:

1 <= n <= 20

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

模拟,一圈一圈打印

package lk2021_03_17;

import java.util.Arrays;

public class Main3 {
    
    
	
	public static void main(String[] args) {
    
    
		Main3 main3 = new Main3();
		int[][] res=main3.generateMatrix(3);
		for (int[] is : res) {
    
    
			System.out.println(Arrays.toString(is));
		}
	}
	
	public int[][] generateMatrix(int n) {
    
    

		int[][] res = new int[n][n];
		int startx=0,starty=0;//定义起始位置
		int loop=n/2;//循环圈数
		int mid=n/2;//矩阵中间位置,n为奇数时单独填充
		int count=1;//起始数字
		int offset=1;//偏移量
		int i,j;
		while (loop-->0) {
    
    
			i=startx;
			j=starty;
			
			//左到右
			for (j = starty; j < starty+n-offset; j++) {
    
    
				res[startx][j]=count++;
			}
			//上到下
			for (i = startx; i < startx+n-offset; i++) {
    
    
				res[i][j]=count++;
				
			}
			//右到左
			for (; j > starty; j--) {
    
    
				res[i][j]=count++;
			}
			
			//下到上
			for (; i > startx; i--) {
    
    
				res[i][j]=count++;
			}
			
			//下一层
			startx++;
			starty++;
			offset+=2;
		}
		
		//n为奇数单独填充中间
		if(n%2!=0) {
    
    
			res[mid][mid]=count;
		}
		return res;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43610675/article/details/114920750