一、力扣
1、最长连续序列

注意是遍历集合!!!否则会超时
java
class Solution {
public int longestConsecutive(int[] nums) {
int ans = 0;
Set<Integer> st = new HashSet<>();
for (int num : nums) {
st.add(num); // 把 nums 转成哈希集合
}
for (int x : st) { // 遍历哈希集合
if (st.contains(x - 1)) {
continue;
}
// x 是序列的起点
int y = x + 1;
while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
y++;
}
// 循环结束后,y-1 是最后一个在哈希集合中的数
ans = Math.max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
}
return ans;
}
}
2、分发饼干

java
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(s);
Arrays.sort(g);
int point=0,traget=0;
for(int i=0;i<s.length&&traget<g.length;i++){
if(s[i]>=g[traget]){
traget++;
point++;
}
}
return point;
}
}
3、买卖股票的最佳时机 II

贪心做法,相邻两天只要有利润,就进行交易
java
class Solution {
public int maxProfit(int[] prices) {
int ans = 0;
int n = prices.length;
for (int i = 1; i < n; ++i) {
ans += Math.max(0, prices[i] - prices[i - 1]);
}
return ans;
}
}
4、摆动序列

1. 贪心

java
class Solution {
public int wiggleMaxLength(int[] nums) {
// 处理特殊情况:数组长度为0或1时,直接返回长度
if (nums.length <= 1) {
return nums.length;
}
// 当前差值(当前元素与前一个元素的差)
int curDiff = 0;
// 上一个有效差值(记录波峰或波谷的变化方向)
int preDiff = 0;
// 计数器,初始为1,因为至少有一个元素
int count = 1;
for (int i = 1; i < nums.length; i++) {
curDiff = nums[i] - nums[i - 1];
// 当当前差值与上一个有效差值符号相反时,说明出现摆动
// 注意:当preDiff为0时(初始状态或连续相等情况),只要当前差值非0即视为有效摆动
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
count++;
preDiff = curDiff; // 更新上一个有效差值
}
}
return count;
}
}
2. 动态规划

java
class Solution {
public int wiggleMaxLength(int[] nums) {
// dp[i][0]表示以nums[i]为波峰时的最长摆动子序列长度
// dp[i][1]表示以nums[i]为波谷时的最长摆动子序列长度
int[][] dp = new int[nums.length][2];
// 初始化:每个元素自身至少可以构成长度为1的子序列
for(int i=0;i<nums.length;i++){
Arrays.fill(dp[i],1);
}
for (int i = 1; i < nums.length; i++) {
// 遍历所有可能的j < i,更新状态
for (int j = 0; j < i; j++) {
if (nums[j] > nums[i]) {
// 当前元素nums[i]比nums[j]小,可作为波谷
// 取nums[j]作为波峰时的最长长度,并加上当前元素
dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
} else if (nums[j] < nums[i]) {
// 当前元素nums[i]比nums[j]大,可作为波峰
// 取nums[j]作为波谷时的最长长度,并加上当前元素
dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
}
// 若nums[j] == nums[i],不影响状态,无需处理
}
}
// 最终结果取最后一个元素作为波峰或波谷的最大值
return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
}
}
5、最大子数组和

dp[i]为以nums[i]结尾的最大子数组和。
java
class Solution {
public int maxSubArray(int[] nums) {
int res=nums[0];
int n=nums.length;
int[] dp=new int[n];
dp[0]=res;
for(int i=1;i<n;i++){
dp[i]=nums[i]+Math.max(0,dp[i-1]);
res=Math.max(dp[i],res);
}
return res;
}
}
java
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 1){
return nums[0];
}
int sum = Integer.MIN_VALUE;
int count = 0;
for (int i = 0; i < nums.length; i++){
count += nums[i];
sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
if (count <= 0){
count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
}
}
return sum;
}
}
6、跳跃游戏

java
class Solution {
public boolean canJump(int[] nums) {
int n=nums.length;
int nexright=0;
for(int i=0;i<n;i++){
if(i<=nexright){
nexright=Math.max(nexright,i+nums[i]);
}else{
return false;
}
}
return true;
}
}