[leetcode] 第六周作业

来源:互联网 发布:华容道java源代码 编辑:程序博客网 时间:2024/05/16 04:14

题目一

453.Minimum Moves to Equal Array Elements

Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1.

Example:

Input: [1,2,3]

Output: 3

Explanation: Only three moves are needed (remember each move
increments two elements):

[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

分析

为了快速的缩小差距,该选择哪些数字加1呢,不难看出每次需要给除了数组最大值的所有数字加1,这样能快速的到达平衡状态。所以一开始我便老老实实的每次找出最大值,然后给其他数字加1,再判断是否平衡,思路正确,但是超时。

借鉴了网上的思路,需要换一个角度来看问题,其实给n-1个数字加1,效果等同于给那个未被选中的数字减1,那么问题也可能转化为,将所有数字都减小到最小值,这样难度就大大降低了,我们只要先找到最小值,然后累加每个数跟最小值之间的差值即可

代码

class Solution {public:    int minMoves(vector<int>& nums) {        int MIN = INT_MAX, sum = 0;        for (int i = 0; i < nums.size(); i++) MIN = min(MIN, nums[i]);        for (int j = 0; j < nums.size(); j++) sum += nums[j] - MIN;        return sum;    }};

题目二

349.Intersection of Two Arrays

Given two arrays, write a function to compute their intersection.

Example:

Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].

Note:

Each element in the result must be unique.
The result can be in any order.

分析

我们可以用个set把nums1都放进去,然后遍历nums2的元素,如果在set中存在,说明是公共部分,加入结果的set中,最后再把结果转为vector的形式即可

代码

class Solution {public:    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {        vector<int> v;        set<int> s(nums1.begin(), nums1.end());        for (int i = 0; i < nums2.size(); i++) {            if (s.count(nums2[i])) {                v.push_back(nums2[i]);                s.erase(nums2[i]);            }        }        return v;    }};

题目三

350.Intersection of Two Arrays II

Given two arrays, write a function to compute their intersection.

Example:

Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].

Note:

Each element in the result should appear as many times as it shows inboth arrays.
The result can be in any order.

解法一

用map来建立nums1中字符和其出现个数之间的映射, 然后遍历nums2数组,如果当前字符在哈希表中的个数大于0,则将此字符加入结果res中,然后哈希表的对应值自减1

class Solution {public:    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {        vector<int> v;        map<int, int> m;        for (int i = 0; i < nums1.size(); i++) m[nums1[i]]++;        for (int i = 0; i < nums2.size(); i++) {            m[nums2[i]]--;            if (m[nums2[i]] >= 0) v.push_back(nums2[i]);        }        return v;    }};
  • 与该解法通用的另一道题目:

383.Ransom Note

Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.

Each letter in the magazine string can only be used once in your ransom note.

canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true

class Solution {  //无序版匹配public:    bool canConstruct(string ransomNote, string magazine) {        if (!ransomNote.size()) return true;        if (ransomNote.size() && !magazine.size()) return false;        vector<int> v(26, 0);        for (int i = 0; i < magazine.size(); ++i)            ++v[magazine[i] - 'a'];        for (int i = 0; i < ransomNote.size(); ++i) {            --v[ransomNote[i] - 'a'];            if (v[ransomNote[i] - 'a'] < 0) return false;        }        return true;    }};

解法二

先给两个数组排序,然后用两个指针分别指向两个数组的起始位置,如果两个指针指的数字相等,则存入结果中,两个指针均自增1,如果第一个指针指的数字大,则第二个指针自增1

class Solution {public:    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {        vector<int> res;        int i = 0, j = 0;        sort(nums1.begin(), nums1.end());        sort(nums2.begin(), nums2.end());        while (i < nums1.size() && j < nums2.size()) {            if (nums1[i] == nums2[j]) {                res.push_back(nums1[i]);                i++;                 j++;            } else if (nums1[i] > nums2[j]) {                j++;            } else {                i++;            }        }        return res;    }};
原创粉丝点击