leetcode个人秋季赛总结(太菜了,只写出两题)


T1: 无人机方阵

此题有坑,直接哈希计数后,注意不能单一的+1计数,因为可能存在多个相同的元素重叠,应该+上绝对值。
OJ平台

解题代码

class Solution {
public:
    int minimumSwitchingTimes(vector<vector<int>>& source, vector<vector<int>>& target) {
        int check[10004];memset(check,0,sizeof(check));
        int n = source.size(),m = source[0].size();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                check[source[i][j]]++;
                check[target[i][j]]--;
            }
        }
        int cnt = 0;
        for(int i=0;i<=10000;i++){
            if(check[i]<0)
                cnt+=abs(check[i]);
        }
        return cnt;
    }
};

T2:心算挑战

很多大佬都是简短的贪心写法,我是傻乎乎花了两小时写了个dp😂
OJ平台

解题思路

当需要形成一个奇数时,我们必须是一奇一偶,当需要形成一个偶数时我们必须两偶或者两奇。

  • 根据上面的特性,我们构建dp关系:

dp[0][i] 代表取了 i 个元素且结果为偶数的情况的最大值。
dp[1][i] 代表取了 i 个元素且结果为奇数的情况的最大值。

  • 转移方程:

dp[偶][i] = max(dp[偶][i],dp[奇][i-1]+odd[pos])
dp[偶][i] = max(dp[偶][i],dp[偶][i-1]+even[pos])

dp[奇][i] = max(dp[奇][i],dp[奇][i-1]+even[pos])
dp[奇][i] = max(dp[奇][i],dp[偶][i-1]+odd[pos])

  • 实际上奇数的更新情况只要写其中一个就行了,因为这两个值肯定是相同的。

现在状态转移方程想好了,但是怎么保证 odd 和 even 中取值每次都是最大且不重复的呢?

我们将odd和even按照从大到小排序并且定义一个结构体:

//由于排序后总是从左到右取值
//evenpos表示当前状态下even数组中取到了哪个下标
//oddpos表示当前状态下odd数组中取到了哪个下标
struct ss {
    int val;
    int evenpos;
    int oddpos;
    ss(): val(0), evenpos(0), oddpos(0) {}
};

解题代码

class Solution {
public:
    //用于动态规划的结构体,其中val存下当前状态的值,
    //evenpos表示当前状态偶数选择到了哪一个位置,oddpos表示奇数选择到了哪一个位置
    struct ss {
        int val;
        int evenpos;
        int oddpos;
        ss(): val(0), evenpos(0), oddpos(0) {}
    };
    int maxmiumScore(vector<int>& cards, int cnt) {
        //创建奇偶结果统计
        vector<int>odd, even;
        for (int i = 0; i < cards.size(); i++) {
            if (cards[i] % 2) {
                odd.emplace_back(cards[i]);
            } else {
                even.emplace_back(cards[i]);
            }
        }
        //为奇偶数组从大到小排序,方便选择
            sort(odd.rbegin(), odd.rend());
            sort(even.rbegin(), even.rend());

        //创建dp数组遍历答案    
        ss dp[2][cnt + 1];
        //用于记录该状态是否被更新,防止出现无答案的cnt次状态被转移
        bool check[2][cnt + 1];
        memset(check, 0, sizeof(check));
        //base case:
        if (even.size()) {
            dp[0][1].val = even[0]; dp[0][1].evenpos++;
            check[0][1] = 1;
        }
        if (odd.size()) {
            dp[1][1].val = odd[0]; dp[1][1].oddpos++;
            check[1][1] = 1;
        }

        //开始进行更新状态转移,dp[0][i].val代表取i个数为偶数时的最大值,dp[1][i].val为取奇数时的最大值
        //为了解决每次加的奇偶数不重复的问题,所以结构体添加了每个状态下的奇偶最新下标取值(反正已经排好序了)
        for (int i = 2; i <= cnt; i++) {
            if (check[1][i - 1] && dp[1][i - 1].oddpos < odd.size() && dp[0][i].val < dp[1][i - 1].val + odd[dp[1][i - 1].oddpos]) {
                check[0][i] = 1;
                dp[0][i].val = dp[1][i - 1].val + odd[dp[1][i - 1].oddpos];
                dp[0][i].oddpos = dp[1][i - 1].oddpos + 1;
                dp[0][i].evenpos = dp[1][i - 1].evenpos;
            }
            if (check[0][i - 1] && dp[0][i - 1].evenpos < even.size() && dp[0][i].val < dp[0][i - 1].val + even[dp[0][i - 1].evenpos]) {
                check[0][i] = 1;
                dp[0][i].val = dp[0][i - 1].val + even[dp[0][i - 1].evenpos];
                dp[0][i].oddpos = dp[0][i - 1].oddpos;
                dp[0][i].evenpos = dp[0][i - 1].evenpos + 1;
            }
            if (check[0][i - 1] && dp[0][i - 1].oddpos < odd.size() && dp[1][i].val < dp[0][i - 1].val + odd[dp[0][i - 1].oddpos]) {
                check[1][i] = 1;
                dp[1][i].val = dp[0][i - 1].val + odd[dp[0][i - 1].oddpos];
                dp[1][i].oddpos = dp[0][i - 1].oddpos + 1;
                dp[1][i].evenpos = dp[0][i - 1].evenpos;
            }
        //由于奇数情况只需要更新一种就行了
            // if (check[1][i - 1] && dp[1][i - 1].evenpos < even.size() && dp[1][i].val < dp[1][i - 1].val + even[dp[1][i - 1].evenpos]) {
            //     check[1][i] = 1;
            //     dp[1][i].val = dp[1][i - 1].val + even[dp[1][i - 1].evenpos];
            //     dp[1][i].oddpos = dp[1][i - 1].oddpos;
            //     dp[1][i].evenpos = dp[1][i - 1].evenpos + 1;
            // }
        }
        return dp[0][cnt].val;
    }
};

总结

  1. 求稳:一旦某种方法一直错误,不要怀疑自己的思路,肯定是哪个小细节出错了。
  2. 求快:不要因小失大,要总览全题,不要因为一道题而放弃了所有。

学到了什么:
在这次中自己按照思路写出了DP,这算是最大的收获了!

### 回答1: class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(len(nums)): for j in range(i+1, len(nums)): if nums[i] + nums[j] == target: return [i, j] ### 回答2: leetcode 第1题是"两数之和",题目要求在给定的整数数组中找到两个数,使它们的和等于一个目标值,并返回这两个数的索引。下面是使用哈希表解决这个问题的Python代码: ```python def twoSum(nums, target): # 创建一个空的哈希表 hashmap = {} # 遍历整个数组 for i, num in enumerate(nums): # 计算当前数字与目标值的差值 complement = target - num # 如果差值存在于哈希表中,则返回差值的索引和当前数字的索引 if complement in hashmap: return [hashmap[complement], i] # 将当前数字添加到哈希表中,索引作为键,数字作为值 hashmap[num] = i # 如果未找到符合条件的数字,则返回空列表 return [] ``` 这个算法的基本思想是,在遍历整个数组的过程中,先计算当前数字与目标值的差值,然后将差值与当前数字的索引存储在哈希表中。接下来,在遍历数组的过程中,如果差值存在于哈希表中,则说明找到了两个数的和等于目标值,直接返回这两个数的索引。如果遍历完成后仍未找到符合条件的数对,则返回空列表。这个算法的时间复杂度为 O(n),其中 n 为数组的长度。 ### 回答3: 题目描述:两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。 示例: 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 思路:使用字典存储数组中的数字及其对应的下标,然后遍历数组找到与目标值的差值,如果差值也在字典中,说明找到了答案。 具体实现如下: ```python def twoSum(nums, target): # 创建一个字典存储数组中的数字及其对应的下标 num_dict = {} for i in range(len(nums)): # 计算与目标值的差值 complement = target - nums[i] # 如果差值也在字典中,说明找到了答案 if complement in num_dict: return [num_dict[complement], i] # 将数字及其对应的下标存入字典中 num_dict[nums[i]] = i return [] nums = [2, 7, 11, 15] target = 9 result = twoSum(nums, target) print(result) # 输出 [0, 1] ``` 以上就是 LeetCode 第1题的 Python 解题代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值