1、合并区间
将数组按照数组第一个值大小进行排序,然后遍历时比较临近数组的首尾数字 引入list
,用来存储结果
public static int[][] merge(int[][] intervals) {List<int[]> lists = new ArrayList<int[]>();Arrays.sort(intervals, new Comparator<int[]>() { //排序@Overridepublic int compare(int[] o1, int[] o2) {return Integer.compare(o1[0], o2[0]);}}); 表达式写法 Arrays.sort(intervals,(a,b)-> a[0] - b[0]);for (int i = 0; i < intervals.length; i++) {int left = intervals[i][0];int right = intervals[i][1];if (lists.size() == 0 || lists.get(lists.size() - 1)[1] < left) {lists.add(new int[]{left, right}); //如果第一个,且遍历较大数字} else {//取当前遍历数字和上一个存储的数字最大值。lists.get(lists.size() - 1)[1] = Math.max(lists.get(lists.size() - 1)[1], right);}}return lists.toArray(new int[lists.size()][]);}
2、轮转数组
模拟运算
nums = "----->-->"; k =3result = "-->----->";reverse "----->-->" we can get "<--<-----"reverse "<--" we can get "--><-----"reverse "<-----" we can get "-->----->"this visualization help me figure it out :)
实际运算
public void rotate(int[] nums, int k) {int len = nums.length;k = k % nums.length;reverse(nums, 0, len - 1);reverse(nums, 0, k-1);reverse(nums, k, len - 1);}public void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;start+=1;end -= 1;}}
3、除自身以外数组的乘积
基础版
由于是算除自身以外数组的乘积,因此以当前遍历的为中心,算出当前数字的左右两边的乘积和,然后将左右两边的乘积进行相乘
class Solution {public int[] productExceptSelf(int[] nums) {int len = nums.length;int[] answer = new int[nums.length];int[] right = new int[len]; // 存储从当前位置右侧的所有元素的乘积int[] left = new int[len]; // 存储从当前位置左侧的所有元素的乘积int leftSum = 1;int rightSum = 1;left[0] = 1; // 初始化左侧乘积为1for (int i = 1; i < len; i++) {left[i] = left[i - 1] * nums[i - 1]; // 计算左侧乘积}right[len - 1] = 1; // 初始化右侧乘积为1for (int i = len - 2; i >= 0; i--) {right[i] = right[i + 1] * nums[i + 1]; // 计算右侧乘积}for (int i = 0; i < len; i++) {answer[i] = left[i] * right[i]; // 将左侧乘积和右侧乘积相乘得到答案}return answer;}}
优化
由于在计算左右两边的乘积和时,会申请2n的空间,因此,在计算过程各种可以复用answer 由于没有右侧乘积,因此需要定义一个变量来记录右侧的乘积
public int[] productExceptSelf(int[] nums) {int len = nums.length;int[] answer = new int[len];answer[0] = 1;for (int i = 1; i < len; i++) {answer[i] = answer[i - 1] * nums[i-1];}int rightSum = 1; //右侧乘积之和for (int i = len-1; i >= 0; i--) {answer[i] = answer[i] * rightSum;rightSum *= nums[i];}return answer;}
其他
思想同二,不过更加简洁,但是由于fill操作更占时间,所以时间耗时更长,且for中难以理解记忆。
public int[] productExceptSelf(int[] nums) {int n=nums.length;int[] ans=new int[n];Arrays.fill(ans,1);int beforeSum=1;int afterSum=1;for(int i=0,j=n-1;i<n;i++,j--){ans[i]*=beforeSum;ans[j]*=afterSum;beforeSum*=nums[i];afterSum*=nums[j];}return ans;}
