leetcode1 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
//1.0 暴力枚举
//时间复杂度O(n^2) 空间复杂度O(1)
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i = 0; i<nums.length;i++){
for(int j = i+1;j<nums.length;j++){
if(nums[j] == target - nums[i]){
return new int[]{i,j};
}
}
}
return new int[0];
}
}
//2.0 哈希表
//时间复杂度O(n) 空间复杂度O(n) 哈希表可以减少查找target-num[i]的时间
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0; i < nums.length;i++){
if(map.containsKey(target - nums[i])){
return new int[]{i,map.get(target-nums[i])};
}
map.put(nums[i],i);
}
return new int[0];
}
}
leetcode 48 旋转图像
class Solution {
public void rotate(int[][] matrix) {
// 先转置后镜像对称
int len = matrix.length;
for(int i = 0; i<len;i++){
for(int j=i;j<len;j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
for(int i=0;i<len;i++){
for(int j=0;j<len/2;j++){
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][len-j-1];
matrix[i][len-j-1] = tmp;
}
}
}
}
leetcode 56 合并区间
https://leetcode-cn.com/problems/merge-intervals/solution/he-bing-qu-jian-by-leetcode-solution/
class Solution {
public int[][] merge(int[][] intervals) {
int len = intervals.length;
// 根据intervals[i][0]的大小进行排序
Arrays.sort(intervals, (a,b)->(a[0]-b[0]));
List<int[]> res = new ArrayList<>();
for(int i=0;i<len;i++){
if(res.size()==0 || intervals[i][0]>res.get(res.size()-1)[1]){
res.add(intervals[i]);
}else{
res.get(res.size()-1)[1] = Math.max(res.get(res.size()-1)[1], intervals[i][1]);
}
}
return res.toArray(new int[res.size()][]);
}
}
leetcode59 螺旋矩阵II
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
//生成一个 n×n 空矩阵 mat,随后模拟整个向内环绕的填入过程:
//定义当前左右上下边界 l,r,t,b,初始值 num = 1,迭代终止值 tar = n * n;
//当 num <= tar 时,始终按照 从左到右 从上到下 从右到左 从下到上 填入顺序循环,每次填入后:
//执行 num += 1:得到下一个需要填入的数字;
//更新边界:例如从左到右填完后,上边界 t += 1,相当于上边界向内缩 1。
//使用num <= tar而不是l < r || t < b作为迭代条件,是为了解决当n为奇数时,矩阵中心数字无法在迭代过程/中被填充的问题。
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int l=0,r=n-1,t=0,b=n-1;
int end = n*n;
int count = 1;
while(count<=end){
for(int i = l; i<=r; i++) matrix[t][i] = count++;//从左向右
t++;
for(int i = t; i<=b; i++) matrix[i][r] = count++;//从上到下
r--;
for(int i = r; i>=l; i--) matrix[b][i] = count++;//从右到左
b--;
for(int i = b; i>=t; i--) matrix[i][l] = count++;//从下到上
l++;
}
return matrix;
}
}
leetcode 54 螺旋矩阵
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> list = new ArrayList<Integer>();
int m = matrix.length;
int n = matrix[0].length;
int l=0,r=n-1,t=0,b=m-1;
while(true){
for(int i=l;i<=r;i++) list.add(matrix[t][i]);//从左到右
if(++t>b) break;
for(int i=t;i<=b;i++) list.add(matrix[i][r]);//从上到下
if(--r<l) break;
for(int i=r;i>=l;i--) list.add(matrix[b][i]);//从右到左
if(--b<t) break;
for(int i=b;i>=t;i--) list.add(matrix[i][l]);//从下到上
if(++l>r) break;
}
return list;
}
}
剑指offer 03数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
**示例 1:**
输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3
```java
//1.0 使用HashSet 时间复杂度O(n) 空间复杂度O(n)
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> dic = new HashSet<Integer>();
for(int num : nums){
if(dic.contains(num)){
return num;
}
dic.add(num);
}
return -1;
}
}
//2.0 原地交换
class Solution {
public int findRepeatNumber(int[] nums) {
int temp;
int len = nums.length;
for(int i=0;i<len;i++){
while(nums[i]!=i){
if(nums[i] == nums[nums[i]]) return nums[i];
temp = nums[nums[i]];
nums[nums[i]] = nums[i];
nums[i] = temp;
}
}
return -1;
}
}
- leetcode 66 加一
```java
//v1.0 考虑全为9时特殊情况,新建一个数组,比较麻烦,有时间可思考简单方法
class Solution {
public int[] plusOne(int[] digits) {
int carry = 0;
int len = digits.length;
boolean allNine = true;
for(int i=0;i<len;i++){
if(digits[i]==9){
continue;
}else{
allNine = false;
break;
}
}
if(allNine){
int[] res = new int[len+1];
res[0] = 1;
return res;
}else{
int sum = digits[len-1]+1;
digits[len-1] = sum%10;
carry = sum/10;
if(carry==1){
for(int i =len-2;i>=0;i--){
int temp = digits[i]+carry;
digits[i] = temp%10;
carry = temp/10;
}
return digits;
}else{
return digits;
}
}
}
}
- leetcode 560 和为K的子数组
//v1.0 暴力解法
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
int len = nums.length;
for(int i=0;i<len;i++){
int sum=0;
for(int j=i;j<len;j++){
sum+=nums[j];
if(sum==k) res++;
}
}
return res;
}
}
//v2.0 使用前缀+hashmap
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
int len = nums.length;
int sum=0;
Map<Integer,Integer> map = new HashMap<>();//map来存储前缀信息
map.put(0,1);
for(int i=0;i<len;i++){
sum+=nums[i];
if(map.containsKey(sum-k)){
res+=map.get(sum-k);
}
map.put(sum,map.getOrDefault(sum,0)+1); //维护map
}
return res;
}
}
leetcode1248 统计优美子数组
//v1.0 暴力解法 超时
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
int res=0;
int flag=0;
int len = nums.length;
for(int i=0;i<len;i++){
flag=0;
for(int j=i;j<len;j++){
if(nums[j]%2==1) flag++;
if(flag==k) res++;
}
}
return res;
}
}
//v2.0 前缀和+hashmap查找
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
int res=0;
int flag=0;
int len = nums.length;
Map<Integer,Integer> map = new HashMap<>();
map.put(0,1);
for(int i=0;i<len;i++){
if(nums[i]%2==1) flag++;
if(map.containsKey(flag-k)){
res+=map.get(flag-k);
}
map.put(flag,map.getOrDefault(flag,0)+1);
}
return res;
}
}
leetcode31 下一个排列
class Solution {
public void nextPermutation(int[] nums) {
int len = nums.length;
if(len==1){
return;
}
// 从数组中的倒数开始遍历,若找到nums[i]<nums[i+1],则从nums[i+1]到nums[len-1]中找到比nums[i]大,但是相对而言最小的与nums[i]交换,之后的数组进行排序
int i= len-2;
for(;i>=0;i--){
if(nums[i]<nums[i+1]){
break;
}
}
if(i==-1){
Arrays.sort(nums);
return;
}
int index = i+1;
for(int j=i+1;j<len;j++){
if(nums[j]>nums[i]&&nums[j]<nums[index]){
index = j;
}
}
swap(nums,index,i);
Arrays.sort(nums, i+1, len);
}
public void swap(int[] nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
leetcode36 有效的数独
class Solution {
public boolean isValidSudoku(char[][] board) {
//验证某个数字在行中是否已经存在
boolean[][] rowValid = new boolean[9][9];
//验证某个数字在列中是否已经存在
boolean[][] columnValid = new boolean[9][9];
//验证某个数字在块中是否已经存在
boolean[][] blockVaild = new boolean[9][9];
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.'){
continue;
}
int num = board[i][j]-'1';
int row = i;
int column = j;
int block = i/3*3+j/3;
if(rowValid[i][num]||columnValid[j][num]||blockVaild[block][num]){
return false;
}
rowValid[i][num] = true;
columnValid[j][num] = true;
blockVaild[block][num] = true;
}
}
return true;
}
}
leetcode128 最长连续序列
class Solution {
public int longestConsecutive(int[] nums) {
int res = 0;
Set<Integer> set = new HashSet<>();
for(int num:nums){
set.add(num);
}
for(int num:set){
if(!set.contains(num-1)){
int tmpLen = 1;
int tmpNum = num;
while(set.contains(tmpNum+1)){
tmpLen++;
tmpNum++;
}
res = Math.max(res, tmpLen);
}
}
return res;
}
}
leetcode 287 寻找重复数
class Solution {
public int findDuplicate(int[] nums) {
int slow = nums[0];
int quick = nums[nums[0]];
while(slow!=quick){
slow = nums[slow];
quick = nums[nums[quick]];
}
int tmp = 0;
while(tmp!=slow){
tmp = nums[tmp];
slow = nums[slow];
}
return slow;
}
}
leetcode 560 和为K的子数组
// v1.0 前缀和
class Solution {
public int subarraySum(int[] nums, int k) {
int len = nums.length;
int[] preSum = new int[len+1];
for(int i=1;i<=len;i++){
preSum[i] = preSum[i-1] + nums[i-1];
}
int res = 0;
for(int i=0;i<len;i++){
for(int j=i+1;j<len+1;j++){
if((preSum[j]-preSum[i])==k){
res++;
}
}
}
return res;
}
}
// v2.0 前缀和+哈希表
class Solution {
public int subarraySum(int[] nums, int k) {
int len = nums.length;
int preSum = 0;
Map<Integer,Integer> map = new HashMap<>();
map.put(0,1);
int res = 0;
for(int i=0;i<len;i++){
preSum+=nums[i];
res += map.getOrDefault(preSum-k,0);
map.put(preSum, map.getOrDefault(preSum,0)+1);
}
return res;
}
}
leetcode581 最短无序连续子数组
class Solution {
public int findUnsortedSubarray(int[] nums) {
// 从左往右,记录最大值,若当前值小于最大值,则说明需要调整
int len = nums.length, high = -1, max = Integer.MIN_VALUE;
for(int i=0; i<len; i++){
max = Math.max(max, nums[i]);
if(nums[i]<max){
high = i;
}
}
// 从右往左,记录最小值,若当前值大于最小值,则说明需要调整
int low = -1, min = Integer.MAX_VALUE;
for(int i=len-1;i>=0;i--){
min = Math.min(min, nums[i]);
if(nums[i]>min){
low = i;
}
}
return low+high==-2? 0:high-low+1;
}
}