7月1日的五题

    技术2022-07-10  147

    718. 最长重复子数组

    53. 最大子序和

    54. 螺旋矩阵

    55. 跳跃游戏

    56. 合并区间

    ---------------------------------分割线-----------------------------------------

    718. 最长重复子数组

    Difficulty: 中等

    给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。

    示例 1:

    输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释: 长度最长的公共子数组是 [3, 2, 1]。

    说明:

    1 <= len(A), len(B) <= 10000 <= A[i], B[i] < 100

    Solution:动态规划

    (关键地方)定义状态:dp[i][j]是以A[i]和B[j] 结尾 的字母的最长子数组的长度,这样才需要更新状态

    class Solution { public int findLength(int[] A, int[] B) { //定义状态:dp[i][j]是以A[i]和B[j]结尾的字母的最长子数组的长度吧,这样才需要更新状态 int[][] dp = new int[A.length+1][B.length+1]; int res = 0; //初始化:[0][0]、[0][i]、[i][0]都是0 for(int i=1; i<=A.length; i++){ for(int j=1; j<=B.length; j++){ if(A[i-1] == B[j-1]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = 0; res = Math.max(dp[i][j], res); } } return res; } }

    53. 最大子序和

    Difficulty: 简单

    给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    示例:

    输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

    进阶:

    如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

    Solution:num[i] 之前的还要不要

    class Solution { public int maxSubArray(int[] nums) { int count = nums[0], sum = nums[0]; for(int i=1; i<nums.length; i++){ if(count > 0){ //之前的大于0,我就要着 count += nums[i]; } else{ //否则就把之前的丢弃掉 count = nums[i]; } sum = Math.max(sum, count); // 每次都找最大值 } sum = Math.max(sum, count); return sum; } }

    54. 螺旋矩阵

    Difficulty: 中等

    给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

    示例 1:

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

    示例 2:

    输入: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] 输出: [1,2,3,4,8,12,11,10,9,5,6,7]

    Solution:确定四个角,这样方便遍历,注意:下 可能和 上 重复, 左 可能和 右 重复

    class Solution { public List<Integer> spiralOrder(int[][] matrix) { List<Integer> res = new ArrayList<>(); int top, bottom, left, right, m, n; m = matrix.length; if(m <= 0) return res; n = matrix[0].length; if(n <= 0) return res; // 固定四个角 top = 0; left = 0; bottom = m-1; right = n-1; while(top <= bottom && left <= right){ //一层一层的遍历 for(int i=left; i<=right; i++){ //上 res.add(matrix[top][i]); } for(int i=top+1; i<=bottom; i++){ //右 res.add(matrix[i][right]); } if(top != bottom){ for(int i=right-1; i>=left; i--){ //下,可能和上重复 res.add(matrix[bottom][i]); } } if(left != right){ for(int i=bottom-1; i>top; i--){ //左,可能和右重复 res.add(matrix[i][left]); } } top++; bottom--; left++; right--; } return res; } }

    55. 跳跃游戏

    Difficulty: 中等

    给定一个非负整数数组,你最初位于数组的第一个位置。

    数组中的每个元素代表你在该位置可以跳跃的最大长度。

    判断你是否能够到达最后一个位置。

    示例 1:

    输入: [2,3,1,1,4] 输出: true 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。

    示例 2:

    输入: [3,2,1,0,4] 输出: false 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

    Solution:贪心算法,从右到左寻找最大的跳数

    class Solution { public boolean canJump(int[] nums) { //贪心算法,从右到左寻找最大的跳数 int len = nums.length, index; //index表示当前位置 if(len <= 0) return false; index = len-1; while(index > 0){ int flag = index; for(int i=index-1; i>=0; i--){ if(index-i <= nums[i]){ index = i; } } if(flag == index) return false; //说明index没变过 } return true; } }

    56. 合并区间

    Difficulty: 中等

    给出一个区间的集合,请合并所有重叠的区间。

    示例 1:

    输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

    示例 2:

    输入: [[1,4],[4,5]] 输出: [[1,5]] 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

    Solution:先对区间的第一维进行排序,然后找每个小区间的最大值和最小值

    import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Random; class Solution { public int[][] merge(int[][] intervals) { List<int[]> res = new ArrayList<>(); int len = intervals.length; if(len <= 0) return new int[0][2]; quickSort(intervals); //排序 //寻找小区间的最大值和最小值: //最小值一定是第一个区间的左边 //最大值需要寻找 //如果某个区间的左边,大于之前的最大值,说明这个区间和之前就不可能合并 int low = intervals[0][0], high = intervals[0][1]; for(int i=1; i<len; i++){ if(high < intervals[i][0]){ //区间的左边大于之前的最大值,不能合并 int[] temp = new int[2]; temp[0] = low; temp[1] = high; res.add(temp); low = intervals[i][0]; high = intervals[i][1]; } else{ high = Math.max(high, intervals[i][1]); } } int[] temp = new int[2]; temp[0] = low; temp[1] = high; res.add(temp); int[][] val = new int[res.size()][2]; for(int i=0; i<res.size(); i++){ val[i] = res.get(i); } return val; } //---------------------随机快速排序-------------------------- public void quickSort(int[][] intervals){ sortHelp(intervals, 0, intervals.length-1); } Random random = new Random(); public void sortHelp(int[][] intervals, int low, int high){ if(low > high) return; int flag = random.nextInt(high-low+1)+low; //生成(low, high)之间的随机数 int partition = intervals[flag][0]; swap(intervals, low, flag); int l = low, h = high; while(l < h){ while(l<h && intervals[h][0]>=partition){ h--; } if(l<h){ swap(intervals, l, h); } while(l<h && intervals[l][0]<=partition){ l++; } if(l<h){ swap(intervals, l, h); } } sortHelp(intervals, low, l-1); sortHelp(intervals, l+1, high); } public void swap(int[][] intervals, int i, int j){ int[] temp = intervals[i]; intervals[i] = intervals[j]; intervals[j] = temp; } }
    Processed: 0.016, SQL: 9