leetcode 174 周赛题解

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

题意:

返回二维数组,每行1的个数的排序。

代码:

python

class Solution:
    def kWeakestRows(self, mat, k) :
        ans = [[sum(line), i] for i , line in enumerate(mat)]
        ans.sort(key = lambda  x:x[0])
        return [ans[i][1] for i in range(k)]

c++

class Solution {
public:
    vector kWeakestRows(vector>& mat, int k) {
        vector vec;
        for(int i=0;i ans;
        for(int i=0;i

c++里,默认对二维的vector进行sort是对其键值排序。

1338. 数组大小减半

题意:

代码:

class Solution:
    def minSetSize(self, arr: List[int]) -> int:
        import collections
        count = collections.Counter(arr)
        order = sorted(count, key = lambda x:count[x], reverse = True)
        print(order)
        all , ans, sum = len(arr), 0, 0 
        for num in order:
            sum += count[num]
            ans +=1
            if sum * 2 >= all:
                return ans

class Solution {
    public:
        int minSetSize(vector& arr) {
            int num[100005];
            memset(num,0,sizeof(num));
            for(int c : arr){
                num[c]+=1;
            }
            sort(num, num+100005, greater());
            int all = arr.size(), sum=0, ans=0;
            for(int i=0;i<1e5+1;i++){
                sum += num[i];
                if(sum*2>= all){
                    ans = i+1;
                    break;
                }
            }
            return ans;
        }
};

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

题意:

在一棵二叉树里,每个节点有一个数值,随意的删除一条边,使分裂的二叉树的乘积尽可能大。

思路:

树型搜索的题目,一遍dfs遍历二叉树,保存以每个节点为根子树的和。 然后枚举删除整个树和这个子树之间的边进行判断。

代码:

class Solution:
    def dfs(self, root):
        self.num[root]  = root.val
        if root.left != None : self.num[root] += self.dfs(root.left)
        if root.right != None: self.num[root] += self.dfs(root.right)
        return self.num[root]

    def maxProduct(self, root) :
        self.num = {}
        self.dfs(root)
        ans, all = 0, self.num[root]
        for node in self.num:
            ans = max(ans , (all - self.num[node]) *self.num[node])
        return int(ans % (1e9+7))

跳跃游戏 V

思路:

典型动态规划,我们遍历每个点的顺序 从矮到高遍历,然后记录每个点的可移动的最大步数。

这样就可以得到的动态转移方程为:

dp[i] = max(dp[可以去的阶梯])+1;

代码 :

class Solution:
    def maxJumps(self, arr: List[int], d: int) -> int:
        n = len(arr)
        dp = [1] * n
        tmp = [(arr[i], i) for i in range(n)]
        tmp = sorted(tmp)
        for i in range(n):
            height = tmp[i][0]
            index = tmp[i][1]
            l = index -1
            while l>=0 and index -l<=d and arr[l]<arr[index]:
                dp[index] = max(dp[index] , dp[l]+1)
                l-=1
                
            r = index + 1
            while r< n and r-index <=d and arr[r]<arr[index]:
                dp[index] = max(dp[index] , dp[r]+1)
                r+=1
        return max(dp)
class Solution {
public:
	int maxJumps(vector& arr, int d) {
		int n = arr.size();
		vector> temp;
		vector dp(n, 0);
		int res = 1;
		for (int i = 0; i < arr.size(); i++)
			temp.push_back({ arr[i],i });
		sort(temp.begin(), temp.end());

		for (int i = 0; i < n; i++) {
			int index = temp[i][1]; //编号;
			dp[index] = 1;
			//向左找
			for (int j = index - 1; j >= index - d && j >= 0; j--) {
				if (arr[j] >= arr[index]) break;
				if (dp[j] != 0) dp[index] = max(dp[index], dp[j ] + 1);
			}
			//向右找
			for (int j = index + 1; j <= index + d && j < n; j++) {
				if (arr[j] >= arr[index]) break;
				if (dp[j] != 0) dp[index] = max(dp[index], dp[j] + 1);
			}
			res = max(dp[index], res);
		}
		return res;

	}
};

你可能感兴趣的:(每周一题(,hihocode,leetcode))