您的位置:首页 > 其它

[leetcode] 第六周作业

2017-10-13 13:08 337 查看

题目一

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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: