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 使用前缀+hashmapclass 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;}}
