环形数组
快慢指针:最多出现两次的数组,环入口地址
pat型:除开自己的以外的乘积
Map:两数和/三数和/四数和,播放磁带,01数组,连续和为k的数组(含有负数)
滑动窗口:最长不重复子串,t步内差小于k,最小/最大的连续和为k的数组
首尾指针:水桶容量,两数和/三数和/四数和
贪心算法:合并区间,跳跃数组,矩阵面积,会议室,汽车加油
计算机数字转化
锯齿遍历,递增的三元组
环形数组:
给定一个含有正整数和负整数的环形数组 nums。 如果某个索引中的数 k 为正数,则向前移动 k 个索引。相反,如果是负数 (-k),则向后移动 k 个索引。因为数组是环形的,所以可以假设最后一个元素的下一个元素是第一个元素,而第一个元素的前一个元素是最后一个元素。
确定 nums 中是否存在循环(或周期)。循环必须在相同的索引处开始和结束并且循环长度 > 1。此外,一个循环中的所有运动都必须沿着同一方向进行。换句话说,一个循环中不能同时包括向前的运动和向后的运动。
示例 1:
输入:[2,-1,1,2,2]
输出:true
解释:存在循环,按索引 0 -> 2 -> 3 -> 0 。循环长度为 3 。
示例 2:
输入:[-1,2]
输出:false
解释:按索引 1 -> 1 -> 1 … 的运动无法构成循环,因为循环的长度为 1 。根据定义,循环的长度必须大于 1 。
import java.lang.*;
class Solution {
public boolean circularArrayLoop(int[] nums) {
int flag1;//作为前向或者正向运动的标志
int length=0;//长度
for(int i=0;i0){flag1=1;}
else flag1=0;
while((nums[j]+j+nums.length)%nums.length!=i&&flag1!=-1){
if(flag1!=nums[j]/Math.abs(nums[j]))flag1=-1;
length++;
j=(nums[j]+j+nums.length)%nums.length;
}
if(length==0||flag1==-1){break;}
else{
return true;
}
}
return false;
}
}
除开自己的以外的乘积
给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
答案:
除num[i]以外数字的乘积等于数字左边的乘积 乘以数字右边的乘积。转化为找"pat"类型题目
答案一:
class Solution {
public int[] productExceptSelf(int[] nums) {
int leftNums[]=new int [nums.length];//记录i数字左边的乘积
leftNums[0]=1;//第一个数字是1
int rightNums[]=new int [nums.length];//记录i数字右边的乘积
rightNums[nums.length-1]=1;//最后一个数字1
int resultNums[]=new int [nums.length];//除了i以外数字的乘积
for(int i=1;i=0;i--){
rightNums[i]=rightNums[i+1]*nums[i+1];
resultNums[i]=leftNums[i]*rightNums[i];
}
resultNums[nums.length-1]=leftNums[nums.length-1]*rightNums[nums.length-1];
return resultNums;
}
}
答案二:
来源于leetcode解析里 LDouble 的作法
利用单数组res,k记录
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] res = new int[nums.length];
int k = 1;
for(int i = 0; i < res.length; i++){
res[i] = k;
k = k * nums[i]; // 此时数组存储的是除去当前元素左边的元素乘积
}
k = 1;
for(int i = res.length - 1; i >= 0; i--){
res[i] *= k; // k为该数右边的乘积。
k *= nums[i]; // 此时数组等于左边的 * 该数右边的。
}
return res;
}
}
两数和:
解析:利用辅助数组(或者Map)
两次遍历:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map map =new HashMap<>();
for(int i=0;i
一次遍历:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map map =new HashMap<>();
for(int i=0;i
三数和:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
import java.lang.*;
import java.util.*;
class Solution {
public List> threeSum(int[] nums) {
List> list=new LinkedList<>();
int low,high;
int len=nums.length;
Arrays.sort(nums);
for(int i=0;i0&&nums[i]==nums[i-1]) continue;
low=i+1;
high=len-1;
while(low
题目四:四数和
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
import java.lang.*;
import java.util.*;
class Solution {
public List> fourSum(int[] nums, int target) {
List> list=new LinkedList<>();
int len=nums.length;
int low,high;
Arrays.sort(nums);
for(int i=0;i0&&nums[i]==nums[i-1]) continue;
for(int j=i+1;ji+1&&nums[j]==nums[j-1]) continue;
low=j+1;high=len-1;
while(low
最接近的三数和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int ans=nums[0]+nums[1]+nums[2];
for(int i=0;itarget)
end--;
else if(value < target)
begin++;
else return ans;
}
}
return ans;
}
}
01连续子数组
给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组(的长度)。
示例 1:
输入: [0,1]
输出: 2
说明: [0, 1] 是具有相同数量0和1的最长连续子数组。
示例 2:
输入: [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
首先对原数组做处理,将所有的0都变为-1;这样一来 “含有相同数量的 0 和 1 的连续数组” 就等价为 “元素值总和为0的连续数组”。
其后,从头扫一遍数组,并记录当前的前缀和的值,将该值和对应的下标存入到一个标记数组或哈希表中。若该前缀和的值已出现过(即标记数组或哈希中已存在),则说明标记中的下标到当前扫描的下标的这段数组的总和值是为0的。
打个例子: [ -1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1 ] 在扫描完到第四个元素时,前缀和为-2 且未记录过,则将值-2和下标3记录起来。当扫描到 [ -1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1 ] , 此时得到的前缀和为-2,且知道标记中有记录过-2,则说明此刻下标到之前记录的下标的这段数组总和为0 [ -1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1 ]
import java.lang.*;
class Solution {
public int findMaxLength(int[] nums) {
int len=nums.length;
int arr[]=new int [2*len+1];
Arrays.fill(arr, -2);//辨别此位置之前没有数字
int count=0,maxlen=0;
arr[len]=-1;//数组开头处count=0,位置为-1
for(int i=0;i=-1){//即之前出现过此值,说明两个值序列间01数量相同
maxlen=Math.max(maxlen,i-arr[count+len]);
}
else arr[count+len]=i;//只用保留第一次出现此值得位置,后面的不用保留
}
return maxlen;
}
}
含有重复字符的 最长子串:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
解析:利用滑动窗口。一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求。当再进入 a,队列变成了 abca,这时候不满足要求。我们需要对窗口进行移动,即判断
left = Math.max(left,map.get(s.charAt(i)) + 1);
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length()==0) return 0;
HashMap map = new HashMap();
int max = 0;
int left = 0;
for(int i = 0; i < s.length(); i ++){
if(map.containsKey(s.charAt(i))){
left = Math.max(left,map.get(s.charAt(i)) + 1);
}
map.put(s.charAt(i),i);
max = Math.max(max,i-left+1);
}
return max;
}
}
播放磁带::
在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。
返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量。形式上,我们希望索引的数字 i < j 且有 (time[i] + time[j]) % 60 == 0。
示例 1:
输入:[30,20,150,100,40]
输出:3
解释:这三对的总持续时间可被 60 整数:
(time[0] = 30, time[2] = 150): 总持续时间 180
(time[1] = 20, time[3] = 100): 总持续时间 120
(time[1] = 20, time[4] = 40): 总持续时间 60
示例 2:
输入:[60,60,60]
输出:3
解释:所有三对的总持续时间都是 120,可以被 60 整数。
答案一:
class Solution {
public int numPairsDivisibleBy60(int[] time) {
Map map=new HashMap<>();
int count=0;
int len=time.length;//单独运算,防止for循环中每一次遍历都调用此方法,节省时间
for(int i=0;i
注意:
1:相当于依顺序遍历数组,对于先加入的数字,即使存在满足情况但是未能匹配,后加入的数字也会对其进行匹配
2: Map
水桶水量:
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49
解析:两端指针,移动时会将较小的边指针向里移动一位(因为若移动较大的边的指针,面积一定减少)
class Solution {
public int maxArea(int[] height) {
int max=0;
int len=height.length;
int i=0,j=len-1;
while(i!=j){
max=Math.max(Math.min(height[i],height[j])*(j-i),max);
if(height[i]>height[j])j--;
else i++;
}
return max;
}
}
跳跃数组:
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
解法一:
class Solution {
public boolean canJump(int[] nums) {
if(nums.length==0||nums.length==1)return true;
int nowValue=0;
int farValue=nums[nowValue];
int len=nums.length;
while(nowValue!=farValue&&farValue=len-1)return true;
farValue=Math.max(farValue,i+nums[i]);
}
nowValue=farValue;
}
if(farValue>=len-1)return true;
return false;
}
}
重叠区间:
给出一个区间的集合,请合并所有重叠的区间。
示例 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] 可被视为重叠区间。
解析:先将区间按左边界排序。之后只需要判断【区间i的右边界,区间i+1的左边界】的关系即可
class Solution {
public int[][] merge(int[][] intervals) {
List result=new LinkedList<>();
if(intervals.length==0||intervals[0].length==0)return result.toArray(new int [0][]);
Arrays.sort(intervals,(a,b)->a[0]-b[0]);
int i=0,len=intervals.length;
while(i=intervals[i+1][0]){
right=Math.max(right,intervals[i+1][1]);i++;
}
result.add(new int[]{left, right});;i++;
}
return result.toArray(new int [0][]);
}
}
t步内差小于k
给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。
示例 1:
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:
输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false
解法一:利用滑动窗口 大小为k
class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
List list=new ArrayList<>();
for(int i=0;ik)list.remove(0);
}
return false;
}
}
矩阵面积:
leetcode223
在二维平面上计算出两个由直线构成的矩形重叠后形成的总面积。
每个矩形由其左下顶点和右上顶点坐标表示,如图所示。
示例:
输入: -3, 0, 3, 4, 0, -1, 9, 2
输出: 45
解析:
对于相离情况,将矩阵A不动,其周围空间化作四等分【左右上下】
对于相交情况,关键在于找相交矩阵,相交矩阵的四条边都来自于两个矩阵的四条边
class Solution {
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
//相离的情况
int value=(C-A)*(D-B)+(G-E)*(H-F);
if(F>D||H
计算机数字转化:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:
解析:利用队列的思想,先进先出进行组合
new String[] {“0”, “1”, “abc”, “def”, “ghi”, “jkl”, “mno”, “pqrs”, “tuv”, “wxyz”};这样设计的目的是下表与字符串相对应,如2-,"abc"leetcode17
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:
解析:利用队列的思想,先进先出进行组合
new String[] {“0”, “1”, “abc”, “def”, “ghi”, “jkl”, “mno”, “pqrs”, “tuv”, “wxyz”};这样设计的目的是下表与字符串相对应,如2-,“abc”
public List letterCombinations(String digits) {
LinkedList ans = new LinkedList();
if(digits.isEmpty()) return ans;
String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
ans.add("");
for(int i =0; i
public List letterCombinations(String digits) {
LinkedList ans = new LinkedList();
if(digits.isEmpty()) return ans;
String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
ans.add("");
for(int i =0; i
汽车加油:
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
如果题目有解,该答案即为唯一答案。
输入数组均为非空数组,且长度相同。
输入数组中的元素均为非负数。
示例 1:
输入:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
示例 2:
输入:
gas = [2,3,4]
cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。
解析:想清楚两点
1:如果0-i不能达到,则直接从i+1开始(0-i之间任何节点都不能到达)
2:如果总的gas>总的cost,则一定存在某节点能遍历。则从遍历到n-1的那个i+1开始的结点即是所求得节点
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int total = 0, sum = 0, start = 0;
for (int i = 0; i < gas.length; ++i) {
total += gas[i] - cost[i];
sum += gas[i] - cost[i];
if (sum < 0) {
start = i + 1;
sum = 0;
}
}
return (total < 0) ? -1 : start; // total 小于 0,说明总消耗大于总油量,那必定无法行驶完所有站点
}
}
环入口地址
解析:
1:假设链表环外长度F,环内长度C
2:slow节点走了长度F,fast节点走了2F,此时在环内的h=Fmod C点
3:再走C-h步两者相遇,slow=(C-h)mod C fast=(2C-2h+h)mod C=(2C-h)modC=(C-h)mod C
4:此时新设指针prt,让fast和pr同时前进,走F步两者在入口处相遇。fasto=(C-FmodC+F)modC=0
public class Solution {
private ListNode getIntersect(ListNode head) {
ListNode tortoise = head;
ListNode hare = head;
while (hare != null && hare.next != null) {
tortoise = tortoise.next;
hare = hare.next.next;
if (tortoise == hare) {
return tortoise;
}
}
return null;
}
public ListNode detectCycle(ListNode head) {
if (head == null) {
return null;
}
ListNode intersect = getIntersect(head);
if (intersect == null) {
return null;
}
ListNode ptr1 = head;
ListNode ptr2 = intersect;
while (ptr1 != ptr2) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
return ptr1;
}
}
长度为sum的最短连续子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
解析:要有意识,遇见连续数组,运用滑动窗口
class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length==0)return 0;
int begin=0,end=0,minLength=Integer.MAX_VALUE,sum=nums[begin];
while(begin<=end&&ends){
minLength=Math.min(minLength,end-begin+1);
sum=sum-nums[begin];
begin++;
}
if(sum
会议室:
给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。
示例 1:
输入: [[0, 30],[5, 10],[15, 20]]
输出: 2
示例 2:
输入: [[7,10],[2,4]]
输出: 1
class Solution implements Comparator {
public int minMeetingRooms(int[][] intervals) {
if(intervals.length==0)return 0;
int []endTime =new int[intervals.length];
int count=0;
Arrays.sort(intervals,this);
endTime[count]=intervals[0][1];
int length=1,flag=0;
while(length=endTime[i]){
endTime[i]=intervals[length][1];
flag=1;
break;
}
}
if(flag==0){
count++;
endTime[count]=intervals[length][1];
}
length++;
flag=0;
}
return count+1;
}
public int compare(int a[],int b[]){
return a[0]-b[0];
}
}
小于target的三数和
给定一个长度为 n 的整数数组和一个目标值 target,寻找能够使条件 nums[i] + nums[j] + nums[k] < target 成立的三元组 i, j, k 个数(0 <= i < j < k < n)。
示例:
输入: nums = [-2,0,1,3], target = 2
输出: 2
解释: 因为一共有两个三元组满足累加和小于 2:
[-2,0,1]
[-2,0,3]
class Solution {
public int threeSumSmaller(int[] nums, int target) {
if(nums.length<3)return 0;
Arrays.sort(nums);
int result=0;
for(int i=0;i=target-nums[i])right--;
else{
result+=right-left;
left++;right=nums.length-1;
}
}
}
return result;
}
}
锯齿遍历:
给出两个一维的向量,请你实现一个迭代器,交替返回它们中间的元素。
示例:
输入:
v1 = [1,2]
v2 = [3,4,5,6]
输出: [1,3,2,4,5,6]
解析: 通过连续调用 next 函数直到 hasNext 函数返回 false,
next 函数返回值的次序应依次为: [1,3,2,4,5,6]。
拓展:假如给你 k 个一维向量呢?你的代码在这种情况下的扩展性又会如何呢?
拓展声明:
“锯齿” 顺序对于 k > 2 的情况定义可能会有些歧义。所以,假如你觉得 “锯齿” 这个表述不妥,也可以认为这是一种 “循环”。例如:
输入:
[1,2,3]
[4,5,6,7]
[8,9]
输出: [1,4,8,2,5,9,3,6,7].
public class ZigzagIterator {
Queue> queue = new LinkedList<>();
public ZigzagIterator(List v1, List v2) {
Iterator it1 = v1.iterator();
Iterator it2 = v2.iterator();
if (it1.hasNext()) {
queue.add(it1);
}
if (it2.hasNext()) {
queue.add(it2);
}
}
public int next() {
Iterator it = queue.poll();
int v = it.next();
if (it.hasNext()) {
queue.add(it);
}
return v;
}
public boolean hasNext() {
if (!queue.isEmpty()) {
return true;
}
return false;
}
}
最大连续和为k的数组(含有负数)
给定一个数组 nums 和一个目标值 k,找到和等于 k 的最长子数组长度。如果不存在任意一个符合要求的子数组,则返回 0。
注意:
nums 数组的总和是一定在 32 位有符号整数范围之内的。
示例 1:
输入: nums = [1, -1, 5, -2, 3], k = 3
输出: 4
解释: 子数组 [1, -1, 5, -2] 和等于 3,且长度最长。
示例 2:
输入: nums = [-2, -1, 2, 1], k = 1
输出: 2
解释: 子数组 [-1, 2] 和等于 1,且长度最长。
class Solution {
public int maxSubArrayLen(int[] nums, int k) {
if(nums == null || nums.length == 0){
return 0;
}
HashMap map = new HashMap<>();
int sum = 0;
int res = 0;
for(int i=0; i
递增的三元组
给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。
数学表达式如下:
如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,
使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。
示例 1:
输入: [1,2,3,4,5]
输出: true
示例 2:
输入: [5,4,3,2,1]
输出: false
class Solution {
public boolean increasingTriplet(int[] nums) {
int index1=Integer.MAX_VALUE,index2=Integer.MAX_VALUE;
for(int i=0;iindex1&&nums[i]index2)return true;
}
return false;
}
}