3.18 3.19 LeetCode 第 174 场周赛

1337. 矩阵中战斗力最弱的 K 行

  • 题目大意
    n*m的矩阵,每行有1代表士兵,0代表平民,问战斗力最弱的k行(按战斗力输出)。

  • 思路

  • code

class Solution {
    #define N 110
    struct node{
        int num,index;
    }a[N];
    static bool cmp(struct node &a, struct node &b){
        
        if(a.num==b.num) return a.index<b.index;
        return a.num<b.num;
    }
        
public:
    vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
        int n = mat.size();
        int m = mat[0].size(); 
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++) a[i].num+=mat[i][j],a[i].index=i;
        }
        sort(a,a+n,cmp);
        vector<int> ans(k,0);
        for(int i=0;i<k;i++) ans[i]=a[i].index;
        return ans;
    }
};

1338. 数组大小减半

  • 题目大意
    你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。返回 至少 能删除数组中的一半整数的整数集合的最小大小。
  • 思路
    贪心 今年可能删除出现次数多的。
  • code
class Solution {
    #define N 100005

    static bool cmp(int a,int b){
        return a>b;
    }
public:
    int minSetSize(vector<int>& arr) {
        int n = arr.size();
        int mp[N]={0};
        for(int i=0;i<n;i++) mp[arr[i]]++;
        sort(mp,mp+N,cmp);
        int ans=0,tot=0;
        for(int i=0;i<n;i++)
        {
            tot+=mp[i];cout<<tot<<endl;
            if(tot>=n/2) return i+1;
            
        }
        return n;
    }
};

1339. 分裂二叉树的最大乘积

  • 题目大意
    给定一颗二叉树,现在将其中的任意一条边删掉,求分开的两部分子树和的最大乘积。
  • 思路
    dfs 虽然给定的数据结构比较奇怪 但是还是一样的dfs就ok了
  • code
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    #define N 50005
    #define ll long long
    ll ans=0,tot=0;
    void dfs(TreeNode* now)
    {
        if(!now) return;
        tot+=now->val;
        dfs(now->left);
        dfs(now->right);
    }

    int dfs2(TreeNode* now)
    {
        if(!now) return 0;
        int temp = dfs2(now->left)+dfs2(now->right)+now->val;
        if(abs(ans*2-tot)>abs(temp*2-tot)) ans=temp;
        return temp;
    }
public:
    int maxProduct(TreeNode* root) {

        ll mod = 1000000007;
        dfs(root);
        dfs2(root);

        return ans*(tot-ans)%mod;
    }
};

1340. 跳跃游戏 V

  • 题目大意
    有长度为n的序列arr,每个点i可以跳到 i + x ( 0 < x < = d , i + x < n ) i+x(0<x<=d,i+x<n) i+x(0<x<=d,i+x<n)或者 i − x ( 0 < x < = d , i − x > = 0 ) i-x(0<x<=d,i-x>=0) ix(0<x<=d,ix>=0)并且要保证从 i i i x x x之间的数都要小于 a r r [ i ] arr[i] arr[i]。可以从任一点出发,问从某一点出发最多可以到达多少个点。
  • 思路
    dp[i]=max(dp[i],dp[x]+1),x为遍历(i-d,i+d)之间的合法的数。
    那么我们要从哪里处罚是无从得知的,因此可以采用记忆化搜索方法。
    注意遍历的顺序,要从离i最近的点开始,要不然答案是错的。
  • code
class Solution {

    #define N 1010
    int dp[N]={0},st[N]={0};
    int ans=0,n;
    int dfs(int x,int d,vector<int>& arr)
    {
        if(st[x]) return dp[x];
        st[x]=1;
        for(int i=x-1;i>=max(0,x-d)&&arr[i]<arr[x];i--) dp[x]=max(dp[x],dfs(i,d,arr)+1);
        for(int i=x+1;i<min(n,x+d+1)&&arr[i]<arr[x];i++) dp[x]=max(dp[x],dfs(i,d,arr)+1);
        return dp[x];
    }
public:
    int maxJumps(vector<int>& arr, int d) {
        n =arr.size();
        for(int i=0;i<n;i++) dp[i]=1;
        for(int i=0;i<n;i++) dp[i]=dfs(i,d,arr);
        for(int i=0;i<n;i++) ans=max(ans,dp[i]);
        for(int i=0;i<n;i++) cout<<dp[i]<<endl;
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值