算法第一周:HashMap有关题目

来源:互联网 发布:mac mini 安装 win10 编辑:程序博客网 时间:2024/06/03 05:27

第一周选择有关hashmap的题目,其中主要用到c++中的map数据结构.

- 525. Contiguous Array

Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

目标:找到0和1个数相等的最长子串的长度。

需要0和1的个数相等,可以考虑将所有的0赋值为-1,再用一个向量记录前i项的和。可以注意到若前i项和出现0的话,从数组开始到该项的子串必定包含相等的0和1,又注意到任意两项前i项和相等的项之间必含有相等的0和1.
解法:令结果result=0.建立map<int,int> m来记录每个前i项和第一次出现的位置。注意:m[0]=-1(前i项和为0出现在第0项之前。遍历数组,用sum记录前i项和,若m中找到sum:result=max(result,i-m[sum]),否则:m[sum]=i。

class Solution {public:    int findMaxLength(vector<int>& nums) {        for(int i=0;i<nums.size();i++)            if(nums[i]==0)                nums[i]=-1;        int sum=0;        vector<int> sums;        for(int i=0;i<nums.size();i++)        {            sum+=nums[i];            sums.push_back(sum);         }         map<int,int> m;        for(int i=0;i<sums.size();i++)        {            m[sums[i]]=i;        }        int result=0;        for(int i=0;i<sums.size();i++)        {            int temp=sums[i];            if(temp==0)                result=max(result,i+1);            else                 result=max(result,m[temp]-i);        }        return result;    }};

- 508. Most Frequent Subtree Sum

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.

Examples 1
Input:

  5 /  \2   -3

return [2, -3, 4], since all the values happen only once, return all of them in any order.
Examples 2
Input:

  5 /  \2   -5

return [2], since 2 happens twice, however -5 only occur once.

  • Definition for a binary tree node.
    • struct TreeNode {
    • int val;
    • TreeNode *left;
    • TreeNode *right;
    • TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    • };

目标:找到所有子树的和,并返回出现次数最多的值。

首先使用一个深度优先搜索算法遍历所有子树,将所有根节点的值改为左子树值+右子树值+根值,同时建立一个map<int,int> one每出现一个新值,便让one[root->val]++。最后遍历one,返回出现次数最多的值(若有多个则返回多个)。

class Solution {public:    map<int,int> one;    vector<int> findFrequentTreeSum(TreeNode* root) {        vector<int> result;        int maxone=0;//记录最大出现次数        dfs(root);        map<int,int>::iterator iter;        for(iter=one.begin();iter!=one.end();iter++)        {            maxone=max(maxone,iter->second);        }        for(iter=one.begin();iter!=one.end();iter++)        {            if(iter->second==maxone)                result.push_back(iter->first);        }        return result;    }    void dfs(TreeNode* root)    {        if(root==NULL) return ;        if(root->left)        {            dfs(root->left);            root->val+=root->left->val;        }        if(root->right)        {            dfs(root->right);            root->val+=root->right->val;        }        one[root->val]++;    }};

- 454. 4Sum II

Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.

目标:找到四个数i,j,k,l使得对四个数组A,B,C,D,A[i]+B[j]+C[k]+D[l]==0,共存在多少个这样的数字组合.

解题思路:首先想到暴力穷举法,果不其然超时了,使用map来提高效率。建立一个map<int,int> nums,遍历前两个数组,记录其所有出现元素和的个数,再遍历后两个数组,寻找是否存在为相反数的元数和。

class Solution {public:    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {        int sum=0;        int size=A.size();        map<int,int> nums;        for(int i=0;i<size;i++)            for(int j=0;j<size;j++)        {            nums[A[i]+B[j]]=nums[A[i]+B[j]]+1;        }         for(int i=0;i<size;i++)            for(int j=0;j<size;j++)        {            sum+=nums[-C[i]-D[j]];        }        return sum;    }};

- 451. Sort Characters By Frequency

Given a string, sort it in decreasing order based on the frequency of characters.

目标:按字符串中字符出现的数目按顺序排列字符。

使用map<char,int>容器来记录不同字符出现的次数,每次选择出现次数最多的字符按其出现的次数添加到目标字符串中。

class Solution {public:    string frequencySort(string s) {        map<char,int> nums;        for(int i=0;i<s.length();i++)        {            nums[s[i]]++;        }        char key;        int max=0;        string x="";        while(!nums.empty())        {            map<char,int>::iterator iter;            for(iter=nums.begin();iter!=nums.end();iter++)            {                if(iter->second>max)                {                    max=iter->second;                    key=iter->first;                }            }            while(max!=0)            {                x+=key;                max--;            }            nums.erase(key);        }        return x;    }};

- 380. Insert Delete GetRandom O(1)

Design a data structure that supports all following operations in average O(1) time.insert(val): Inserts an item val to the set if not already present.remove(val): Removes an item val from the set if present.getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

目标:编写一个容器能在o(1)复杂度内实现插入,删除,随机取数三个功能。

使用map容器可以实现在o(1)复杂度内插入,删除需要搭配vector容器:用vector存储所有插入的数据,删除时须将map和vector中的同一元素同时删除。用rand()%v.size()在vector中随机取数。

class RandomizedSet {public:    /** Initialize your data structure here. */    RandomizedSet() {    }    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */    bool insert(int val) {        if(hash.count(val))            return false;        else        {            hash[val]=v.size();            v.push_back(val);            return true;        }    }    /** Removes a value from the set. Returns true if the set contained the specified element. */    bool remove(int val) {        if(hash.count(val)==0)        {            return false;        }        else        {            int pos=hash[val];            hash[v.back()]=pos;            swap(v[pos],v[v.size()-1]);            hash.erase(val);            v.pop_back();            return true;        }    }    /** Get a random element from the set. */    int getRandom() {        return v[rand()%v.size()];    }private:    map<int,int> hash;    vector<int> v;};
0 0