T2860
贪心+排序
class Solution {
public int countWays(List<Integer> nums) {
Collections.sort(nums);
int choose = 0;
int ans = 0;
int n = nums.size();
if(nums.get(0)>0){
ans+=1;
}
for(int i = 0;i<n-1;i++){
if(nums.get(i)<i+1&&i+1<nums.get(i+1)){
ans+=1;
}
}
if(nums.get(n-1)<n){
ans+=1;
}
return ans;
}
}
T2861
二分答案
class Solution {
public int maxNumberOfAlloys(int n, int k, int budget, List<List<Integer>> composition, List<Integer> stock, List<Integer> cost) {
//过程中用int会爆上限,所以都用long,最后返回int
long l = 0;
long r = 200000000;//因为答案的最大值是budget+max(stock) <=2*10^8,所以设r为2*10^8
while(l<r){//二分答案查找模版
long mid = (l+r+1)>>1;
if(check(mid,n,k,budget,composition,stock,cost)) l = mid;
else r = mid-1;
}
return (int)l;
}
public boolean check(long lim,int n,int k,int budget,List<List<Integer>> composition,List<Integer> stock, List<Integer> cost){
for(int i = 0;i<k;i++){//遍历总共k台机器
long c = 0;//计算每台机器的制作合金数目的开销
List<Integer> lst = composition.get(i);
for(int j = 0;j<n;j++){//遍历总共n种合金
if(lst.get(j)*lim<=stock.get(j)) continue;
c+=(lst.get(j)*lim - stock.get(j))*cost.get(j);//计算开销
}
if(c<=budget) return true;//如果这台机器的总开销低于预算则可行
}
return false;//没有机器的开销低于预算
}
}
T300
动态规划方法
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
if(n==1) return 1;
int[] dp = new int[n];
Arrays.fill(dp,1);
int ans = 1;
for(int i = 1;i<n;i++){
for(int j = 0;j<i;j++){
if(nums[i]>nums[j]){
dp[i] = Math.max(dp[i],dp[j]+1);
}
}
ans = Math.max(dp[i],ans);
}
return ans;
}
}
二分方法
class Solution {
public int lengthOfLIS(int[] nums) {
List<Integer> q = new ArrayList<>();
for(int i = 0;i<nums.length;i++){
int index = lower_bound(q,nums[i]);
if(index==q.size()) q.add(nums[i]);
else q.set(index,nums[i]);
}
return q.size();
}
private int lower_bound(List<Integer> q,int x){
int l = 0,r = q.size();
while(l<r){
int mid = (l+r)>>>1;
if(q.get(mid)>=x){
r = mid;
}
else{
l = mid+1;
}
}
return l;
}
}
T2560
二分答案
class Solution {
public int minCapability(int[] nums, int k) {
int l = 0;
int r = 0;
for(int x:nums){
r = Math.max(r,x);
}
while(l<r){
int mid = l+r>>1;
if(check(mid,k,nums)){
r = mid;
}
else{
l = mid+1;
}
}
return l;
}
public boolean check(int limit,int k,int[] nums){
int f0 = 0,f1 = 0;
for(int x:nums){
if(x<=limit){
int tmp = f0;
f0 = Math.max(f0,f1);
f1 = Math.max(tmp+1,f1);
}
else{
f0 = Math.max(f0,f1);
}
}
return Math.max(f0,f1)>=k;
}
}
T2653
哈希数组+滑动窗口
class Solution {
public int[] getSubarrayBeauty(int[] nums, int k, int x) {
int[] cnt = new int[101];
for(int i = 0;i<k-1;i++){
cnt[nums[i]+50] +=1;
}
int n = nums.length;
int[] ans = new int[n-k+1];
for(int r = k-1;r<n;r++){
cnt[nums[r]+50]+=1;
int l = r-k+1;
int cc = 0;
for(int c = 0;c<50;c++){
cc+=cnt[c];
if(cc>=x){
ans[l] = c-50;
break;
}
}
cnt[nums[l]+50]-=1;
}
return ans;
}
}
T236
Tarjan算法
class Solution {
Map<TreeNode,TreeNode> query = new HashMap<>();
Map<TreeNode,TreeNode> fa = new HashMap<>();
TreeNode ans = null;
public TreeNode find(TreeNode x){
if(fa.get(x)!=x){
fa.put(x,find(fa.get(x)));
}
return fa.get(x);
}
public boolean tarjan(TreeNode root){
fa.put(root,root);
if(root.left!=null){
if(tarjan(root.left)) return true;
fa.put(root.left,root);
}
if(root.right!=null){
if(tarjan(root.right)) return true;
fa.put(root.right,root);
}
if(query.containsKey(root)&&fa.containsKey(query.get(root))){
ans = find(fa.get(query.get(root)));
return true;
}
return false;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
query.put(p,q);
query.put(q,p);
tarjan(root);
return ans;
}
}
大跳算法(略)
T2857
哈希表+位运算
class Solution {
public int countPairs(List<List<Integer>> coordinates, int k) {
Map<Integer,Map<Integer,Integer>> cnt = new HashMap<>();
int ans = 0;
for(List<Integer> c:coordinates){
int x = c.get(0),y = c.get(1);
for(int i = 0;i<=k;i++){
int acc = cnt.getOrDefault(i^x,new HashMap<>()).getOrDefault((k-i)^y,0);
ans+=acc;
}
if(!cnt.containsKey(x)){
cnt.put(x,new HashMap<>());
}
cnt.get(x).merge(y,1,(v1,v2)->(v1+v2));
}
return ans;
}
}
T2830
分组动态规划
class Solution {
public int maximizeTheProfit(int n, List<List<Integer>> offers) {
List<int[]>[] edge = new ArrayList[n];
Arrays.setAll(edge,e->new ArrayList<>());
int[] f = new int[n+1];
for(var o:offers){
edge[o.get(1)].add(new int[]{o.get(0),o.get(2)});
}
int ans = 0;
for(int i = 0;i<n;i++){
if(i>0) f[i] = f[i-1];
for(var e:edge[i]){
f[i] = Math.max(f[i],e[1]);
if(e[0]>0){
f[i] = Math.max(f[i],e[1]+f[e[0]-1]);
}
}
ans = Math.max(ans,f[i]);
}
return ans;
}
}
T2850
暴力全排列
class Solution {
int ans = Integer.MAX_VALUE;
public int minimumMoves(int[][] grid) {
List<Integer> st = new ArrayList<>();
List<Integer> empty = new ArrayList<>();
for(int i = 0;i<3;i++){
for(int j = 0;j<3;j++){
if(grid[i][j]==0){
empty.add(i*3+j);
}
if(grid[i][j]>1){
for(int k = 0;k<grid[i][j]-1;k++){
st.add(i*3+j);
}
}
}
}
int[] vis = new int[9];
List<Integer> tmp = new ArrayList<>();
int n = st.size();
dfs(n,0,vis,tmp,st,empty);
return ans;
}
public int dis(int i,int j){
return Math.abs(i/3-j/3)+Math.abs(i%3-j%3);
}
public void dfs(int n,int deep,int[] vis,List<Integer> tmp,List<Integer> st,List<Integer> empty){
if(deep ==n){
int d = 0;
for(int i = 0;i<n;i++){
d+=dis(tmp.get(i),empty.get(i));
}
ans = Math.min(ans,d);
}
else{
for(int i= 0;i<n;i++){
if(vis[i] == 1) continue;
vis[i] = 1;
tmp.add(st.get(i));
dfs(n,deep+1,vis,tmp,st,empty);
tmp.remove(tmp.size()-1);
vis[i] = 0;
}
}
}
}
T2812
多源bfs+二分答案
class Solution {
int[] dx = new int[]{0,1,0,-1};
int[] dy = new int[]{1,0,-1,0};
public int maximumSafenessFactor(List<List<Integer>> grid) {
int m = grid.size(),n = grid.get(0).size();
int[][] martix = new int[m][n];
for(int i = 0;i<m;i++){
Arrays.fill(martix[i],-1);
}
Deque<Integer> q = new LinkedList<>();
for(int i = 0;i<m;i++){
for(int j = 0;j<n;j++){
if(grid.get(i).get(j).equals(1)){
q.add(i*m+j);
martix[i][j] = 0;
}
}
}
int layer = 1;
q.add(null);
while(q.isEmpty()==false){
if(q.peek() == null){
q.poll();
layer+=1;
if(q.isEmpty()==true){
break;
}
q.add(null);
}
else{
int cur = q.poll();
int x = cur/m,y = cur%m;
for(int k = 0;k<4;k++){
int xx = x+dx[k];
int yy = y+dy[k];
if(xx>=0&&xx<m&&yy>=0&&yy<n&&martix[xx][yy]==-1){
q.add(xx*m+yy);
martix[xx][yy] = layer;
}
}
}
}
int l=0,r = Math.min(martix[0][0],martix[m-1][n-1]);
System.out.println(r);
while(l<r){
int mid = (l+r+1)/2;
if(check(mid,m,n,martix)) l = mid;
else r = mid-1;
}
return l;
}
public boolean check(int lim,int m,int n,int[][] martix){
int[][] vis = new int[m][n];
Deque<Integer> q = new LinkedList<>();
q.add(0);
vis[0][0] = 1;
while(q.isEmpty()==false){
int cur = q.poll();
int x = cur/m,y = cur%m;
for(int k = 0;k<4;k++){
int xx = x+dx[k];
int yy = y+dy[k];
if(xx>=0&&xx<m&&yy>=0&&yy<n&&vis[xx][yy]==0&&martix[xx][yy]>=lim){
vis[xx][yy]=1;
q.add(xx*m+yy);
}
}
}
return vis[m-1][n-1] == 1;
}
}