【第一题】三个数的最大乘积
分析:注意注意!有负数出没!!
方法1:
1.最小的两个负数相乘,再乘以最大的正数,得出sum1;
2.直接让三个最大的正数相乘,得出sum2;
3.比较sum1和sum2,返回更大的那个。
时间主要消耗在了这个排序上面。
方法二:线性扫描(找最小的两个数和最大的三个数)
//执行用时:12 ms, 在所有 Java 提交中击败了69.75% 的用户
//内存消耗:39.8 MB, 在所有 Java 提交中击败了71.82% 的用户
class Solution {
public int maximumProduct(int[] nums) {
if(nums.length == 3){return nums[0] * nums[1] * nums[2];}
Arrays.sort(nums);
int sum1 = 0,sum2 = 0;
sum2 = nums[nums.length-1] * nums[nums.length-2] * nums[nums.length-3];
sum1 = nums[0] * nums[1] * nums[nums.length-1];
return Math.max(sum1,sum2);
}
}
//执行用时:2 ms, 在所有 Java 提交中击败了99.19% 的用户
//内存消耗:39.8 MB, 在所有 Java 提交中击败了67.07% 的用户
public class Solution {
public int maximumProduct(int[] nums) {
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
for (int n: nums) {
if (n <= min1) {
min2 = min1;
min1 = n;
} else if (n <= min2) { // n lies between min1 and min2
min2 = n;
}
if (n >= max1) { // n is greater than max1, max2 and max3
max3 = max2;
max2 = max1;
max1 = n;
} else if (n >= max2) { // n lies betweeen max1 and max2
max3 = max2;
max2 = n;
} else if (n >= max3) { // n lies betwen max2 and max3
max3 = n;
}
}
return Math.max(min1 * min2 * max1, max1 * max2 * max3);
}
}
【第二题】存在连续三个奇数的数组
分析:双指针,遍历一遍,判断过的数没必要再判断。
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:38.1 MB, 在所有 Java 提交中击败了61.66% 的用户
class Solution {
public boolean threeConsecutiveOdds(int[] arr) {
if(arr.length < 3){return false;}
int i = 0,count =0;
for(i = 0;i < arr.length;i++){
if(arr[i] % 2 == 0){
//System.out.println("even:"+arr[i]);
count = 0;
}else{
count++;
if(count == 3){
return true;
}
//System.out.println("odd:"+arr[i]);
}
}
return false;
}
}
【第三题】汇总区间
分析:意思就是,每一组连续的数是一个区间,假如中间缺失了一个数字,就得另外划分区间
方法一:相邻两元素相减看是不是为1即可。(双指针和二分查找的边界是真的难扣,一顿操作猛如虎,提交击败百分五)
方法二:双指针的改进;
//执行用时:9 ms, 在所有 Java 提交中击败了29.32% 的用户
//内存消耗:36.9 MB, 在所有 Java 提交中击败了46.01% 的用户
class Solution {
public List<String> summaryRanges(int[] nums) {
ArrayList<String> list = new ArrayList<>();
if(nums.length == 0){return list;}
if(nums.length ==1){
list.add(nums[0]+"");
return list;
}
int i = 0,j = 1;
while(i < nums.length && j< nums.length){
if(nums[j] - nums[i] == (j-i)){
j++;
}else{
if(j-i == 1){
list.add(nums[i]+"");
i = j;
if(j < nums.length-1){
j++;
}else{
break;
}
}
if(j - i > 1){
list.add(nums[i]+"->"+nums[j-1]);
i = j;
if(j < nums.length-1){
j++;
}else{
break;
}
}
}
}
//第一种情况
if(j==i){
list.add(nums[i]+"");
}
//第二种情况
if(j - i>1){
list.add(nums[i]+"->"+nums[j-1]);
}
return list;
}
}
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:36.4 MB, 在所有 Java 提交中击败了94.54% 的用户
class Solution {
public List<String> summaryRanges(int[] nums) {
List<String> ret = new ArrayList<String>();
int i = 0;
int n = nums.length;
while (i < n) {
int low = i;
i++;
while (i < n && nums[i] == nums[i - 1] + 1) {
i++;
}
int high = i - 1;
StringBuffer temp = new StringBuffer(Integer.toString(nums[low]));
if (low < high) {
temp.append("->");
temp.append(Integer.toString(nums[high]));
}
ret.add(temp.toString());
}
return ret;
}
}
【第四题】种花问题
分析:看有连续几个0,另外还得考虑封口的0还是不封口的0
要考虑一个元素的两边分别是什么。
【第五题】翻转图像
分析:先逆序翻转,再0,1翻转。(一遍AC,大人的快乐就这么简单)
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:38.7 MB, 在所有 Java 提交中击败了43.60% 的用户
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
for(int i = 0;i < A.length;i++){
A[i] = reverse(A[i]);
for(int j = 0;j < A[i].length;j++){
if(A[i][j] == 0){
A[i][j] = 1;
}else{
A[i][j] = 0;
}
}
}
return A;
}
public int[] reverse(int[] nums){
int i = 0,j = nums.length-1;
while(i < j){
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
i++;
j--;
}
return nums;
}
}
【第六题】最富有客户的资产总量
分析:一次AC(要做点重拳出击的题才能增强自信)
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:38.3 MB, 在所有 Java 提交中击败了16.33% 的用户
class Solution {
public int maximumWealth(int[][] accounts) {
int max = 0;
for(int i = 0;i < accounts.length;i++){
int sum = 0;
for(int j = 0;j < accounts[i].length;j++){
sum+=accounts[i][j];
}
max = Math.max(sum,max);
}
return max;
}
}
【第七题】找出井字棋的获胜者
【第八题】统计好三元组
【第九题】数组序号转换
分析:首先去重是个大问题,去完重排序,然后排序后将数组下标对应数组元素即可。
去重:https://blog.csdn.net/u010680097/article/details/52353369
方法一:列表去重+哈希映射;
方法二:
//居然超时了
class Solution {
public int[] arrayRankTransform(int[] arr) {
int[] ret = new int[arr.length];
if(arr.length == 0){return ret;}
if(arr.length == 1){ret[0] = 1;return ret;}
ArrayList<Integer> list = new ArrayList<>();
Map<Integer,Integer> map = new HashMap<>();
for(int i = arr.length-1;i >=0;i--){
if(!list.contains(arr[i])){
list.add(arr[i]);
}
}
Collections.sort(list);
for(int i = list.size()-1;i >= 0;i--){
map.put(list.get(i),i+1);
}
for(int j = 0;j < arr.length;j++){
ret[j] = map.get(arr[j]);
}
return ret;
}
}
//直接用哈希表
//执行用时:27 ms, 在所有 Java 提交中击败了77.86% 的用户
//内存消耗:48.1 MB, 在所有 Java 提交中击败了74.67% 的用户
class Solution {
public int[] arrayRankTransform(int[] arr) {
//学到了,还可以直接克隆
int[] temp = arr.clone();
Arrays.sort(temp);
HashMap<Integer,Integer> map = new HashMap<>();
int n = temp.length;
int count = 1;
for(int i = 0;i < n;i++){
if(map.get(temp[i]) == null){
map.put(temp[i],count);
count++;
}
}
for(int i = 0;i < n;i++){
arr[i] = map.get(arr[i]);
}
return arr;
}
}
//数组去重后排序+二分+桶排序
class Solution {
public int[] arrayRankTransform(int[] arr) {
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int num : arr) {
if (num < min) min = num;
if (num > max) max = num;
}
int[] count = new int[max - min + 1];
for (int num : arr)
count[num - min] = 1;
int[] preSum = new int[count.length + 1];
for (int i = 1; i < preSum.length; i++)
preSum[i] = preSum[i - 1] + count[i - 1];
int[] ans = new int[arr.length];
int index = 0;
for (int num : arr)
ans[index++] = preSum[num - min] + 1;
return ans;
}
}
【第十题】至少是其他数字两倍的最大数
分析:
方法一:【排序版】首先将数组排序,找到最大的整数.然后看第二大的数的两倍是否小于等于它即可。
方法二:【不排序版】
//执行用时:2 ms, 在所有 Java 提交中击败了16.56% 的用户
//内存消耗:36.4 MB, 在所有 Java 提交中击败了43.50% 的用户
class Solution {
public int dominantIndex(int[] nums) {
if(nums.length == 1){return 0;}
int[] temp = nums.clone();
Arrays.sort(temp);
int max = temp[nums.length-1];
int index = 0;
int j = nums.length-2;
while(temp[j] == max){
j--;
}
if(temp[j] * 2 <= max){
for(int i = 0;i < nums.length;i++){
if(nums[i] == max){
index = i;
return i;
}
}
}
return -1;
}
}
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:36.3 MB, 在所有 Java 提交中击败了50.31% 的用户
class Solution {
public int dominantIndex(int[] nums) {
int max = Integer.MIN_VALUE;
int index = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] > max){
max = nums[i];
index = i;
}
}
for(int i = 0;i < nums.length;i++){
if(i != index && nums[i]!=max){
if(nums[i]*2 > max){
return -1;
}
}
}
return index;
}
}
【第十一题】斐波那契数
分析:
方法一:递归;
方法二:非递归。
//递归大法好
class Solution {
public int fib(int n) {
if(n == 1||n == 0){return n;}
else{
return fib(n-1) + fib(n-2);
}
}
}
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:35.2 MB, 在所有 Java 提交中击败了29.73% 的用户
class Solution{
public int fib(int n){
if(n == 1||n == 0){return n;}
int[] ret = new int[n+1];
ret[0] = 0;
ret[1] = 1;
int cur = 2;
while(cur <= n){
ret[cur] = ret[cur - 1] + ret[cur - 2];
cur++;
}
return ret[n];
}
}
【第十二题】缀点成线
分析:注意转double!
//执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:38.1 MB, 在所有 Java 提交中击败了52.96% 的用户
class Solution {
public boolean checkStraightLine(int[][] coordinates) {
if(coordinates.length == 2){return true;}
double a = 0,b = 0;
if((coordinates[1][0] - coordinates[0][0])!=0){
a = (double)(coordinates[1][1] - coordinates[0][1])/(coordinates[1][0] - coordinates[0][0]);
b = (double)(coordinates[1][0] * coordinates[0][1] - coordinates[0][0] * coordinates[1][1])/(coordinates[1][0] - coordinates[0][0]);
}else{
for(int i = 2;i < coordinates.length;i++){
if(coordinates[i][0]!=coordinates[0][0]){
return false;
}
}
return true;
}
for(int i = 2;i < coordinates.length;i++){
if(coordinates[i][1] != coordinates[i][0] * a + b){
return false;
}
}
return true;
}
}
【第十三题】数组的度
分析:首先要知道哪个元素出现次数最多,其次要知道该元素首次出现的下标first以及最后一次出现的下标last。
last - first +1即为返回值。
【第十四题】寻找数组的中心索引
分析:首先求出所有元素的总和,然后以数组的每个元素nums[i]作为中心索引,只需要试探nums[i]左边的元素之和是否等于( sum-nums[i] )/2即可,假如小于,那么继续往下设置中心索引,假如大于,直接返回-1。
(注意注意注意!!有负数出没!!)
方法二:leftsum == sum - leftsum - nums[i];只需要在累加的时候顺便判断即可,这样的话,只需要一层for循环
//一顿操作猛如虎,提交超越百分五。
//执行用时:648 ms, 在所有 Java 提交中击败了5.09% 的用户
//内存消耗:39.3 MB, 在所有 Java 提交中击败了34.38% 的用户
class Solution {
public int pivotIndex(int[] nums) {
if(nums.length == 0 || nums.length == 2){return -1;}
if(nums.length == 1){return 0;}
double sum = 0;
for(int i : nums){
sum =(double)sum + i;
}
for(int j = 0;j < nums.length;j++){
double total = 0;
for(int k = 0;k < j;k++){
total =(double)total + nums[k];
}
if(total == (double)(sum - nums[j])/2){
return j;
}
// if(total > 0 && total > (double)(sum - nums[j])/2){
// return -1;
// }
// if(total < 0 && total < (double)(sum - nums[j])/2){
// return -1;
// }
//System.out.println(total);
}
return -1;
}
}
//执行用时:1 ms, 在所有 Java 提交中击败了100.00% 的用户
//内存消耗:39.1 MB, 在所有 Java 提交中击败了59.60% 的用户
class Solution {
public int pivotIndex(int[] nums) {
int sum = 0, leftsum = 0;
for (int x: nums) sum += x;
for (int i = 0; i < nums.length; ++i) {
if (leftsum == sum - leftsum - nums[i]) return i;
leftsum += nums[i];
}
return -1;
}
}
【第十五题】等价多米诺骨牌的数量
分析:
【第十六题】特殊数组的特征值
分析:
//执行用时:2 ms, 在所有 Java 提交中击败了29.21% 的用户
//内存消耗:36 MB, 在所有 Java 提交中击败了78.70% 的用户
class Solution {
public int specialArray(int[] nums) {
Arrays.sort(nums);
for(int i = 0;i < 1000;i++){
for(int j = 0;j < nums.length;j++){
if(nums[j] >= i){
//System.out.println(i + " "+j+" "+(nums.length-j));
if((nums.length - j) == i){
return i;
}else{
break;
}
}
}
}
return -1;
}
}
//执行用时:1 ms, 在所有 Java 提交中击败了93.73% 的用户
//内存消耗:36.3 MB, 在所有 Java 提交中击败了52.87% 的用户
class Solution {
public int specialArray(int[] nums) {
Arrays.sort(nums);
if(nums[0] >= nums.length)//length个值
return nums.length;
for (int i = 1; i <= nums.length; i++) {
if((nums[nums.length -i] >= i && nums[nums.length -i-1] < i ))
return i;
}
return -1;
}
}
【第十七题】珠玑妙算
分析:猜中——>相应位置的字母相同;伪猜中——>字母存在,但是位置错了。
双指针:确定是否猜中;桶:确定伪猜中的次数;
【第十八题】最长连续递增序列
分析:
//执行用时:1 ms, 在所有 Java 提交中击败了99.79% 的用户
//内存消耗:39.2 MB, 在所有 Java 提交中击败了48.68% 的用户
class Solution {
public int findLengthOfLCIS(int[] nums) {
if(nums.length == 0 || nums.length == 1){return nums.length;}
int max = 1,count = 1;
for(int i = 1;i < nums.length;i++){
if(nums[i] > nums[i-1]){
count++;
}else{
max = Math.max(max,count);
count = 1;
}
}
max = Math.max(max,count);
return max;
}
}
【第十九题】将每个元素替换为右侧最大元素
分析:从右往左开始。不断比较得出最大值
//执行用时:3 ms, 在所有 Java 提交中击败了32.65% 的用户
//内存消耗:39.9 MB, 在所有 Java 提交中击败了18.08% 的用户
class Solution {
public int[] replaceElements(int[] arr) {
int[] ret = new int[arr.length];
ret[arr.length - 1] = -1;
int max = arr[arr.length -1];
for(int i = arr.length -2;i>=0;i--){
//System.out.println(max);
ret[i] = Math.max(arr[i+1],max);
max = Math.max(arr[i+1],max);
}
return ret;
}
}
【第二十题】数组拆分I
分析:按照顺序从小到大排序,然后每两个一组,不断加上组内min,最后计算总和。
方法二:计数排序.(没咋看懂) https://leetcode-cn.com/problems/array-partition-i/solution/shu-zu-chai-fen-i-by-leetcode/
//执行用时:14 ms, 在所有 Java 提交中击败了36.73% 的用户
//内存消耗:40.8 MB, 在所有 Java 提交中击败了12.39% 的用户
class Solution {
public int arrayPairSum(int[] nums) {
if(nums.length == 2){return Math.min(nums[0],nums[1]);}
int sum = 0;
Arrays.sort(nums);
for(int i = 0;i < nums.length;i+=2){
sum += Math.min(nums[i],nums[i+1]);
}
return sum;
}
}
public class Solution {
public int arrayPairSum(int[] nums) {
int[] arr = new int[20001];
int lim = 10000;
for (int num: nums)
arr[num + lim]++;
int d = 0, sum = 0;
for (int i = -10000; i <= 10000; i++) {
sum += (arr[i + lim] + 1 - d) / 2 * i;
d = (2 + arr[i + lim] - d) % 2;
}
return sum;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/array-partition-i/solution/shu-zu-chai-fen-i-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。