数组中的第K个最大元素
java
package hot100;
public class lc215 {
/*215. 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题*/
int ans = 0;
public int findKthLargest(int[] nums, int k) {
//堆排序
//定义不会写,默认是最小堆
/*PriorityQueue<Integer> head = new PriorityQueue<>();
for(int i = 0; i < nums.length; i++){
if(!head.isEmpty() && head.size() >= k){
if(nums[i] > head.peek()){
head.poll();
head.offer(nums[i]);
}
}else{
head.offer(nums[i]);
}
}
return head.peek();*/
//写法2:快排
k = nums.length - k ;
kuaipai(nums,0, nums.length-1,k);
return ans;
}
public void kuaipai(int[] nums, int left, int right, int target){
//相等的话,就是整个数字
if(right == left){
ans = nums[left];
return ;
}
int l = left;
int r = right;
int mid = l + (r - l)/2;
int num_mid = nums[mid];
while(l <= r){
while(l <= r && nums[l] < num_mid ){
l++;
}
while(l <= r && nums[r] > num_mid){
r--;
}
//条件要加上!!!
if (l <= r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;}
}
if(target >= l){
kuaipai(nums, l, right, target);
}else if(target <= r){
kuaipai(nums, left, r, target);
}else {
//说明找到位置了,mid都是要找的数字
ans = num_mid;
return;
}
}
public static void main(String[] args) {
lc215 solution = new lc215();
int[] nums = new int[]{3,2,1,5,6,4};
System.out.println(solution.findKthLargest(nums,2));
}
}
347. 前 K 个高频元素
java
package hot100;
import java.util.*;
public class lc347 {
/*347. 前 K 个高频元素
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入:nums = [1,1,1,2,2,3], k = 2
输出:[1,2]*/
public int[] topKFrequent(int[] nums, int k) {
//新的数组
//桶排序,map反过来
Map<Integer, Integer> hashmap = new HashMap<>();
for(int i = 0; i < nums.length; i++){
//getOrDefault(要查的数字,0)
hashmap.put(nums[i], hashmap.getOrDefault(nums[i],0)+1);
}
//桶排序
//注意这个数组
List<Integer>[] buckets = new List[nums.length + 1];
//遍历,keySet()
for(int key : hashmap.keySet()){
int bucket = hashmap.get(key);
//要初始化
if(buckets[bucket] == null){
buckets[bucket] = new ArrayList<>();
}
buckets[bucket].add(key);
}
//开始遍历
int[] ans = new int[k];
int index = 0;
for(int i = nums.length; i >0; i--){
if(buckets[i] != null){
for(int j = 0; j < buckets[i].size() && index < k; j++){
ans[index] = buckets[i].get(j);
index++;
}
}
}
return ans;
}
public static void main(String[] args) {
lc347 solution = new lc347();
int[] nums = new int[]{1,1,1,2,2,3};
int[] ans = solution.topKFrequent(nums,2);
System.out.println(Arrays.toString(ans));
}
}
295. 数据流的中位数
java
package hot100;
import java.util.*;
public class MedianFinder {
/*295. 数据流的中位数
已解答
困难
相关标签
premium lock icon
相关企业
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
例如 arr = [2,3,4] 的中位数是 3 。
例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。
实现 MedianFinder 类:
MedianFinder() 初始化 MedianFinder 对象。
void addNum(int num) 将数据流中的整数 num 添加到数据结构中。
double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。
示例 1:
输入
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]
解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3); // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0
提示:
-105 <= num <= 105
在调用 findMedian 之前,数据结构中至少有一个元素
最多 5 * 104 次调用 addNum 和 findMedian*/
//最小堆和最大堆, 最小堆是出来的最小,最大堆是出来的是最大
//堆用队列的poll和offer
public PriorityQueue<Integer> leftMaxheap;
public PriorityQueue<Integer> rightMinheap;
public MedianFinder() {
leftMaxheap = new PriorityQueue<>((a,b) -> b -a);
rightMinheap= new PriorityQueue<>();
}
public void addNum(int num) {
//左边可以大于右边一个
if(leftMaxheap.isEmpty() || num <= leftMaxheap.peek()){
leftMaxheap.offer(num);
if(leftMaxheap.size() > rightMinheap.size() +1){
rightMinheap.offer(leftMaxheap.poll());
}
}else{
rightMinheap.offer(num);
if(rightMinheap.size() > leftMaxheap.size()){
leftMaxheap.offer(rightMinheap.poll());
}
}
}
public double findMedian() {
if(leftMaxheap.size() == rightMinheap.size()){
return (leftMaxheap.peek() + rightMinheap.peek())/2.0;
}
return leftMaxheap.peek();
}
public static void main(String[] args) {
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
System.out.println(medianFinder.findMedian());; // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3); // arr[1, 2, 3]
System.out.println(medianFinder.findMedian());; // return 2.0
}
}
买卖股票的最佳时机
java
package hot100;
public class lc121 {
/*121. 买卖股票的最佳时机
已解答
简单
相关标签
premium lock icon
相关企业
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。*/
public int maxProfit(int[] prices) {
//前面最小
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for(int price : prices){
min= Math.min(min, price);
max = Math.max(price - min, max);
}
return max;
}
public static void main(String[] args) {
lc121 solution = new lc121();
int[] nums = new int[]{7,1,5,3,6,4};
System.out.println(solution.maxProfit(nums));
}
}
跳跃游戏
java
package hot100;
public class lc55 {
/*55. 跳跃游戏
已解答
中等
相关标签
premium lock icon
相关企业
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标
*/
public boolean canJump(int[] nums) {
//int max
int max = 0;
for(int i = 0; i < nums.length ; i++){
if(i > max){
return false;
}
max = Math.max(max,i+nums[i]);
if(max > nums.length-1){
return true;
}
}
return true;
}
public static void main(String[] args) {
lc55 solution = new lc55();
int[] nums = new int[]{2,3,1,1,4};
System.out.println(solution.canJump(nums));
}
}
跳跃游戏 II
java
package hot100;
public class lc45 {
/*跳跃游戏 II
已解答
中等
相关标签
premium lock icon
相关企业
给定一个长度为 n 的 0 索引整数数组 nums。初始位置在下标 0。
每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:
0 <= j <= nums[i] 且
i + j < n
返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2*/
public int jump(int[] nums) {
//这一步里面的最远
//用两个变量就行,这一步里面的currend, 下一步nextend,每一步都走到最远的地方
int step = 0;
int currend = 0;
int nextend = 0;
//当i== nums.length-1不需要再加了,大于只有一个的数的数组也是
for(int i = 0; i < nums.length-1; i++ ){
nextend = Math.max(nextend,nums[i]+i);
if(i == currend){
currend = nextend;
step++;
}
}
return step;
}
public static void main(String[] args) {
lc45 solution = new lc45();
int[] nums = new int[]{2,3,1,1,4};
System.out.println(solution.jump(nums));
}
}
划分字母区间
java
package hot100;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class lc763 {
/* 划分字母区间
已解答
中等
相关标签
premium lock icon
相关企业
提示
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。例如,字符串 "ababcc" 能够被分为 ["abab", "cc"],但类似 ["aba", "bcc"] 或 ["ab", "ab", "cc"] 的划分是非法的。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。*/
public List<Integer> partitionLabels(String s) {
//记录最后出现的次数
//用数组记录
int[] last = new int[26];
for(int i = 0; i < s.length();i++){
char c = s.charAt(i);
last[c - 'a'] = i;
}
//
List<Integer> ans = new ArrayList<>();
int end = 0;
int start = 0;
for(int i = 0; i < s.length(); i++){
end = Math.max(end, last[s.charAt(i) - 'a']);
if(i == end){
int length = end -start+1;
start = i+1;
ans.add(length);
}
}
return ans;
}
public static void main(String[] args) {
lc763 solution = new lc763();
String s = "ababcbacadefegdehijhklij";
List<Integer> ans = solution.partitionLabels(s);
System.out.println(ans);
}
}
爬楼梯
java
package hot100;
public class lc70 {
/*70. 爬楼梯
已解答
简单
相关标签
premium lock icon
相关企业
提示
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?*/
public int climbStairs(int n) {
int pre=1;
int pre1 =2;
if(n == 1){
return pre;
}
if(n==2){
return pre1;
}
int ans = 0;
for(int i =3; i <=n; i++){
ans = pre + pre1;
pre = pre1;
pre1 =ans;
}
return ans;
}
public static void main(String[] args) {
lc70 solution = new lc70();
System.out.println(solution.climbStairs(3));
}
}
杨辉三角
java
package hot100;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class lc118 {
/*118. 杨辉三角
已解答
简单
相关标签
premium lock icon
相关企业
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。*/
public List<List<Integer>> generate(int numRows) {
int n = numRows;
List<List<Integer>> anss = new ArrayList<>();
if (n == 0)
return anss;
//记住用Arrays.adList
anss.add(new ArrayList<>(Arrays.asList(1)));
if(n==1){
return anss;
}
anss.add(new ArrayList<>(Arrays.asList(1,1)));
if(n==2){
return anss;
}
anss.add(new ArrayList<>(Arrays.asList(1,2,1)));
if(n==3){
return anss;
}
for(int i = 4; i <= n; i++){
List<Integer> ans = new ArrayList<>();
List<Integer> pre = anss.get(i-2);
for(int j = 0; j <i; j++){
if(j == 0){
ans.add(1);
}else if(j == i-1){
ans.add(1);
}else{
ans.add(pre.get(j-1) + pre.get(j));
}
}
anss.add(ans);
}
return anss;
}
public static void main(String[] args) {
lc118 solution = new lc118();
System.out.println(solution.generate(5));
}
}
打家劫舍
java
package hot100;
public class lc198 {
/*打家劫舍
已解答
中等
相关标签
premium lock icon
相关企业
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。*/
public int rob(int[] nums) {
//动态规划
//dp【i] = dp[i-2] + nums[i], dp[i];
int[] dp = new int[nums.length];
if(nums.length == 1){
return nums[0];
}
if(nums.length == 2){
return Math.max(nums[0], nums[1]);
}
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
//max的初始化
int max = Math.max(dp[0], dp[1]);
for(int i = 2; i < nums.length; i++){
//仔细写
dp[i] = Math.max(dp[i-2]+ nums[i], dp[i-1]);
max = Math.max(max,dp[i]);
}
return max;
}
public static void main(String[] args) {
lc198 solution = new lc198();
int[] nums = new int[]{1,2,3,1};
System.out.println(solution.rob(nums));
}
}
完全平方数
java
package hot100;
public class lc279 {
/*279. 完全平方数
已解答
中等
相关标签
premium lock icon
相关企业
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
示例 1:
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
示例 2:
输入:n = 13
输出:2
解释:13 = 4 + 9*/
public int numSquares(int n) {
//动态规划
int[] dp = new int[n+1];
//w为什么没想到?先写状态转移方程,别管复杂度这些,先用最笨的方法把他写出来
dp[0] = 0;
for(int i = 1; i <= n; i++){
dp[i] = i;
for(int j = 1; j*j <= i; j++){
dp[i] = Math.min(dp[i], dp[i-j*j]+1);
}
}
return dp[n];
}
public static void main(String[] args) {
lc279 solution = new lc279();
System.out.println(solution.numSquares(12));
}
}
零钱兑换
java
package hot100;
public class lc322 {
/*322. 零钱兑换
已解答
中等
相关标签
premium lock icon
相关企业
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
示例 3:
输入:coins = [1], amount = 0
输出:0*/
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
dp[0] = 0;
for(int i =1; i <= amount; i++){
dp[i] = i+1;
for(int coin : coins){
//需要两个条件,i-coin也要可以抵达才行
if(i >= coin && dp[i-coin] != i -coin+1)
dp[i] = Math.min(dp[i], dp[i-coin]+1);
}
}
return dp[amount] == amount+1 ? -1: dp[amount];
}
public static void main(String[] args) {
lc322 solution = new lc322();
int[] nums = new int[]{1,2,5};
System.out.println(solution.coinChange(nums,11));
}
}
单词拆分
java
package hot100;
import java.util.Arrays;
import java.util.List;
public class lc139 {
/*139. 单词拆分
已解答
中等
相关标签
premium lock icon
相关企业
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
注意,你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false*/
public boolean wordBreak(String s, List<String> wordDict) {
//dp[i] == dp[i-word]
boolean[] dp = new boolean[s.length() +1];
dp[0] = true;
//我是从i==1开始的,所以可以直接截取(i-长度,i)
for(int i = 1; i <= s.length(); i++){
for(String word : wordDict){
if(i >= word.length() && s.substring(i-word.length(), i).equals(word)){
//dp[i]自己原本行不行,行的话就可以了,需要||自己
dp[i] = dp[i] || dp[i-word.length()];
}
}
}
return dp[s.length()];
}
public static void main(String[] args) {
lc139 solution = new lc139();
// 示例 1
String s1 = "leetcode";
List<String> dict1 = Arrays.asList("leet", "code");
System.out.println(solution.wordBreak(s1, dict1)); // 应输出 true
// 示例 2
String s2 = "applepenapple";
List<String> dict2 = Arrays.asList("apple", "pen");
System.out.println(solution.wordBreak(s2, dict2)); // 应输出 true
// 示例 3
String s3 = "catsandog";
List<String> dict3 = Arrays.asList("cats", "dog", "sand", "and", "cat");
System.out.println(solution.wordBreak(s3, dict3)); // 应输出 false
// 额外测试:空字符串(注意:若 s 为空,dp[0]=true,应返回 true,但通常题目 s 非空)
System.out.println(solution.wordBreak("", Arrays.asList("a"))); // true
}
}
最长递增子序列
java
package hot100;
public class lc300 {
/*300. 最长递增子序列
已解答
中等
相关标签
premium lock icon
相关企业
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1*/
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length+1];
dp[0] = 1;
//一题目是要最大,所以需要一个max来比对最大,部署返回最后一个
int max = 1;
for(int i = 1; i < nums.length; i++){
dp[i] = 1;
for(int j = 0; j <= i;j++ ){
if(nums[j] < nums[i])
dp[i] = Math.max(dp[i], dp[j]+1);
}
max = Math.max(max,dp[i]);
}
return max;
}
public static void main(String[] args) {
lc300 solution = new lc300();
int[] nums = new int[]{10,9,2,5,3,7,101,18};
System.out.println(solution.lengthOfLIS(nums));
}
}
乘积最大子数组
java
package hot100;
public class lc152 {
/*152. 乘积最大子数组
已解答
中等
相关标签
premium lock icon
相关企业
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
请注意,一个只包含一个元素的数组的乘积是这个元素的值。
示例 1:
输入: nums = [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。*/
public int maxProduct(int[] nums) {
//最小,最大都要记录,需要一个max,dp就正常记录
int[] dpmin = new int[nums.length + 1];
int[] dpmax = new int[nums.length + 1] ;
dpmax[0] = nums[0];
dpmin[0]= nums[0];
int max = nums[0];
for(int i = 1; i < nums.length; i++){
dpmax[i] = nums[i];
dpmin[i] = nums[i];
if(nums[i] > 0){
dpmax[i] = Math.max(dpmax[i],dpmax[i-1]*nums[i]);
dpmin[i] = Math.min(dpmin[i],dpmin[i-1]*nums[i]);
}else if(nums[i] <= 0){
dpmax[i] = Math.max(dpmax[i],dpmin[i-1]*nums[i]);
dpmin[i] = Math.min(dpmin[i],dpmax[i-1]*nums[i]);
}
max = Math.max(dpmax[i],max);
}
return max;
}
public static void main(String[] args) {
lc152 solution = new lc152();
int[] nums = new int[]{2,3,-2,4};
System.out.println(solution.maxProduct(nums));
}
}
分割等和子集
java
package hot100;
public class lc416 {
/*416. 分割等和子集
已解答
中等
相关标签
premium lock icon
相关企业
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
示例 1:
输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。
*/
public boolean canPartition(int[] nums) {
int sum = 0;
for(int i = 0; i < nums.length; i++){
sum += nums[i];
}
if(sum % 2== 1){
return false;
}
int n = sum/2;
for(int i = 0; i < nums.length; i++){
if(nums[i] > n){
return false;
}
}
boolean[] dp = new boolean[n+1];
dp[0] = true;
/*for(int i = 1; i < sum+1; i++){
for(int num : nums){
if(i >= num){
dp[i] = dp[i] || dp[i-num];
}
}
}*/
//把num放在外面,这样num的话jiu只会使用一次
for(int num : nums){
for(int i = n; i >= num; i--){
dp[i] = dp[i] || dp[i-num];
}
}
return dp[n];
}
public static void main(String[] args) {
lc416 solution = new lc416();
int[] nums = new int[]{1,5,11,5};
System.out.println(solution.canPartition(nums));
}
}
最长有效括号
java
package hot100;
import java.util.ArrayDeque;
import java.util.Deque;
public class lc32 {
/*32. 最长有效括号
已解答
困难
相关标签
premium lock icon
相关企业
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号 子串 的长度。
左右括号匹配,即每个左括号都有对应的右括号将其闭合的字符串是格式正确的,比如 "(()())"。
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s =*/
public int longestValidParentheses(String s) {
//动态规划
int[] dp = new int[s.length() + 1];
int max = 0;
Deque<Integer> stack = new ArrayDeque<>();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(c == '('){
stack.push(i);
}else{
//要判断前面是不是'('
if(!stack.isEmpty() && s.charAt(stack.peek()) == '('){
int j = stack.pop();
dp[i] = i-j+1 ;
if(j- 1 >= 0 && dp[j-1]!=0){
//弹出来还能喝他的前面连起来
dp[i] = i-j+1 + dp[j-1];
}
max = Math.max(dp[i],max);
}else{
stack.push(i);
}
}
}
return max;
}
public static void main(String[] args) {
lc32 solution = new lc32();
String s = ")()())";
System.out.println(solution.longestValidParentheses(s));
}
}
碎碎念:后续会更新每天学习的八股和算法题,开始准备秋招的第76/77天。努力连续更新100天!以后每天就按,秋招项目【java +agent】,科研,必做项目,算法,八股,锻炼身体来总结。
总结:加油吧
1.hot100 【acm 】 90/100 ,2到3h,快速把hot100过一遍【13/20】
2.秋招项目,【java 项目】,继续
【agent 项目 】,继续
3.科研。确定方向就搞就可以了
4.实习;
6.背八股,无
7.锻炼身体,无
要点:坚持