leetcode363-Max-Sum-of-Rectangle-No-Larger-Than-K

题目要求Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.Example:Input: matrix = [[1,0,1],[0,-2,3]], k = 2Output: 2 Explanation: Because the sum of rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).Note:1. The rectangle inside the matrix must have an area > 0.2. What if the number of rows is much larger than the number of columns?现有一个由整数构成的矩阵,问从中找到一个子矩阵,要求该子矩阵中各个元素的和为不超过k的最大值,问子矩阵中元素的和为多少?注:后面的文章中将使用[左上角顶点坐标,右下角顶点坐标]来表示一个矩阵,如[(1,2),(3,4)]表示左上角顶掉坐标为(1,2),右下角顶点坐标为(3,4)的矩阵。用S[(1,2),(3,4)]表示该矩阵的面积。顶点的坐标系以数组的起始点作为起点,向下为x轴正方向,向右为y轴正方向。 ...

June 7, 2019 · 4 min · jiezi

leetcode327. Count of Range Sum

题目要求Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.Note:A naive algorithm of O(n2) is trivial. You MUST do better than that.Example:Input: nums = [-2,5,-1], lower = -2, upper = 2,Output: 3 Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.这道题目是指,现有一个整数数组,并输入上界值upper和下界值lower,问数组中一共有多少组连续的子数组,其子数组中数字的和在上界和下界之内。思路一:暴力循环我们可以首先遍历一遍数组,计算子数组下标[0,i)的所有元素的和。根据该结果可以计算自数组[i,j)中所有元素的和。接着计算所有子数组中元素的和,并判断是否位于数值区间内。代码如下: public int countRangeSum(int[] nums, int lower, int upper) { long[] sums = new long[nums.length+1]; for(int i = 0 ; i<nums.length ; i++) { sums[i+1] = sums[i] + nums[i]; } int count = 0; for(int i = 0 ; i<nums.length ; i++) { for(int j = i+1 ; j<=nums.length ; j++) { if(sums[j] - sums[i] >= lower && sums[j] - sums[i] <= upper) { count++; } } } return count; }思路二:分治法分治法的核心思路在于,将计算整个数组的符合条件的子数组的问题切分为子问题,将数组一分为二,并分别计算左子数组的符合条件的子数组个数,右子数组中符合条件的子数组个数和横穿左右数组的符合条件的子数组个数。计算横穿左右的子数组个数的方法很有趣,这采用了归并排序的思想,即无论左子数组中的元素或是右子数组中的元素如何变动,横穿左右的子数组个数都不会受影响。因此,在对左右子数组进行排序后,以左子数组中的每一位作为开头,在右子数组中找到满足upper和lower区间的第一个值,和超过upper区间的第一个值。则二者的差即为横穿左右的满足条件的子数组个数。 public int countRangeSum3(int[] nums, int lower, int upper) { long[] sums = new long[nums.length + 1]; for(int i = 0 ; i<nums.length ; i++) { sums[i+1] = sums[i] + nums[i]; } long[] sortedSums = new long[nums.length + 1]; return mergeCountRangeSum3(sums, sortedSums, 0, nums.length+1, lower, upper); } public int mergeCountRangeSum3(long[] sums,long[] sortedSums, int start, int end, int lower, int upper) { if(end - start <= 1) return 0; int mid = (start + end) / 2; int count = mergeCountRangeSum3(sums, sortedSums, start, mid, lower, upper) + mergeCountRangeSum3(sums, sortedSums, mid, end, lower, upper); int firstLargerThanUpper = mid, firstLargerThanLower = mid, indexOfRightHalf = mid; for(int i = start, sortedSumsIndex = start; i < mid ; i++, sortedSumsIndex++) { while(firstLargerThanUpper < end && sums[firstLargerThanUpper] - sums[i] <= upper) firstLargerThanUpper++; while(firstLargerThanLower < end && sums[firstLargerThanLower] - sums[i] <lower) firstLargerThanLower++; while(indexOfRightHalf < end && sums[indexOfRightHalf] < sums[i]) sortedSums[sortedSumsIndex++] = sums[indexOfRightHalf++]; sortedSums[sortedSumsIndex] = sums[i]; count += firstLargerThanUpper - firstLargerThanLower; } System.arraycopy(sortedSums, start, sums, start, indexOfRightHalf - start); return count; } ...

April 18, 2019 · 2 min · jiezi

Java面试题:稳定和不稳定排序算法之间的区别-MergeSort与QuickSort

来源 | 愿码(ChainDesk.CN)内容编辑愿码Slogan | 连接每个程序员的故事网站 | http://chaindesk.cn愿码愿景 | 打造全学科IT系统免费课程,助力小白用户、初级工程师0成本免费系统学习、低成本进阶,帮助BAT一线资深工程师成长并利用自身优势创造睡后收入。官方公众号 | 愿码 | 愿码服务号 | 区块链部落免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码本文阅读时长:6min你是否理解QuickSort与MergeSort之间的区别?你稳定和不稳定的排序算法的含义是什么?当面试官问到以上问题应如何回答?如果排序算法保持数字/记录的相对顺序,即如果需要排序1 1 2 3,那么如果不更改前两个排序的顺序,则认为排序算法是稳定的,但如果交换它们,则尽管总体结果或排序顺序保持不变,但它将变得不稳定。当您对对象进行排序时(例如,按键对键值对进行排序),这种差异会变得更加明显。在稳定算法的情况下,保留键值对的原始顺序,如下例所示。实际上,如果您忘记提及这些概念,面试官可能会将此问题视为快速排序与合并排序的后续工作。quicksort和mergesort之间的主要区别之一是快速排序不稳定,而合并排序是一种稳定的排序算法。顺便说一句,如果您不熟悉Quicksort和Mergesort等基本排序算法,那么我建议您学习下全面的数据结构课程,如数据结构和算法:深度使用Java。它将为您提供进一步探索所需的所有基础知识。稳定与不稳定算法假设您需要按键的递增顺序对以下键值对进行排序:INPUT:(4,5)(3,2)(4,3)(5,4)(6,4)现在,有两个密钥相同的两对的可能解决方案即(4,5)和(4,3)如下所示:OUTPUT1:(3,2),(4,5),(4,3),(5,4),(6,4)OUTPUT2:(3,2 ),(4,3),(4,5),(5,4),(6,4)将产生第一个输出的排序算法称为稳定排序算法,因为保持了相等键的原始顺序,您可以看到(4,5)以排序顺序出现在(4,3)之前,这是原始顺序,即在给定的输入中,(4,5)出现在(4,3)之前。产生第二输出的算法将被称为不稳定的排序算法,因为具有相同键的对象的顺序不按排序顺序维持。你可以看到,在第二个输出中,(4,3)出现在(4,5)之前,原始输入中不是这种情况。现在,最大的问题是稳定和不稳定排序算法的一些例子是什么?那么,你可以把所有众所周知的排序算法分成稳定和不稳定的。稳定算法的一些示例是合并排序,插入排序,冒泡排序和二叉树排序。而QuickSort,堆排序和选择排序是不稳定的排序算法。如果你还记得,Collections.sort()Java Collection框架中的方法使用迭代合并排序,这是一种稳定的算法。如果输入数组被部分排序,它的比较也比NLog(N)少得多。如果您有兴趣了解有关此主题的更多信息,我建议您学习数据结构和算法,比如算法和数据结构-第1部分和第2部分。它是Java程序员算法的综合课程之一。稳定与不稳定算法示例以下图片解释了稳定和不稳定的排序是如何工作的:这就是稳定和不稳定排序算法之间的区别。请记住,如果在排序的输出中保持相等键或数字的原始顺序,则该算法称为排序算法。稳定排序算法的一些常见示例是合并排序,插入排序和冒泡排序。 你还想要知道哪些关于面试题的知识呢?请在下方留言!

April 18, 2019 · 1 min · jiezi