【问题标题】:update and print array element?更新和打印数组元素?
【发布时间】:2015-12-05 14:32:59
【问题描述】:

给定一个由 N 个正整数组成的数组 A1, A2 ,..., AN。

另外,给定 Q 更新形式:- i j:更新 Ai = j。 1≤i≤N。

执行所有更新,并在每次更新后报告阵列的报告模式。因此,返回一个 Q 个元素的数组,其中第 i 个元素是执行第 i 次更新后数组的模式。

注意事项

  • 众数是数组中出现频率最高的元素。
  • 如果可能有多种模式,则返回最小的一种。
  • 更新数组输入是通过 Q*2 数组进行的,其中每一行代表一个更新。

例如,

A=[2, 2, 2, 3, 3]

Updates=    [ [1, 3] ]
            [ [5, 4] ]
            [ [2, 4] ]

A = [3, 2, 2, 3, 3] after 1st update.
3 is mode.

A = [3, 2, 2, 3, 4] after 2nd update.
2 and 3 both are mode. Return smaller i.e. 2.

A = [3, 4, 2, 3, 4] after 3rd update.
3 and 4 both are mode. Return smaller i.e. 3.

Return array [3, 2, 3].
Constraints 
1 ≤ N, Q ≤ 105 
1 ≤ j, Ai ≤ 109

我使用简单数组的实现有什么问题?

  /**
     * @input A : Integer array
     * @input n1 : Integer array's ( A ) length
     * @input B : 2D integer array 
     * @input n21 : Integer array's ( B ) rows
     * @input n22 : Integer array's ( B ) columns
     * 
     * @Output Integer array. You need to malloc memory, and fill the length in len1
     */
    int* getMode(int* A, int n1, int** B, int n21, int n22, int *len1) {
        int *ans = (int *) malloc (sizeof(int)); // dynamic allocation of array 
        int x = 0,i,j;
        for(i = 0; i < n1 ; i ++ )
            for(j = 0; j < n21; j++)
                A[B[j][0]] = B[j][1];
            // frequency calculate  

            int c[n1] ;

            for(i = 0; i < n1; i++)
                c[i] = 0;

            for(i = 0; i < n1; i++)
                c[A[i]]++;

            int mx = INT_MAX;
            int idx = -1, idx1 = -1;

            for(i = 0; i < n1; i++){
                if (mx  < A[i]){
                    idx1 = idx;
                    mx = A[i];
                    idx = i;
                }

            int p;
            if (A[idx]> A[idx1])
                p = A[idx];
            else
                p = A[idx1];

            ans[x++] = p; }

        return ans; }

我们该如何解决呢?任何人都可以提出一些答案吗?

【问题讨论】:

  • 我在这里没有看到问题...
  • 您必须根据给定的注释进行适当的更改,并在每次迭代后打印最频。出现字符??我正在尝试使用优先队列解决它你的建议是什么??
  • 您编写的需要帮助的代码在哪里?

标签: arrays adhoc


【解决方案1】:

unordered_map<int, int> buildElementCnt(vector<int> &A){
    unordered_map<int, int> elementCnt;
    for(int i=0; i<A.size(); i++){
        elementCnt[A[i]]++;
    }
    return elementCnt;
}

map<int, set<int>> buildCntToEls(unordered_map<int, int> & elementCnt){
    unordered_map<int, int> :: iterator it;
    map<int, set<int>> cntToEle;

    for(it=elementCnt.begin(); it!= elementCnt.end(); it++){
        if(cntToEle.find(it->second) != cntToEle.end()){
            cntToEle[it->second].insert(it->first);
        }else{
            set<int> s;
            s.insert(it->first);
            cntToEle[it->second] = s;
        }
    }
    return cntToEle;
}

void removeEle(int ele, unordered_map<int, int> & elementCnt, map<int, set<int>>& cntToEle){
    cntToEle[elementCnt[ele]].erase(cntToEle[elementCnt[ele]].find(ele));
    if(cntToEle[elementCnt[ele]].empty()) cntToEle.erase(elementCnt[ele]);
    if(cntToEle.find(elementCnt[ele] - 1) != cntToEle.end()){
        cntToEle[elementCnt[ele] - 1].insert(ele);
    }else{
        set<int> s;
        s.insert(ele);
        cntToEle[elementCnt[ele] - 1] = s;
    }
    elementCnt[ele]--;
}

void addEle(int ele, unordered_map<int, int> & elementCnt, map<int, set<int>>& cntToEle){
    if(elementCnt.find(ele) != elementCnt.end() && elementCnt[ele] > 0){
        cntToEle[elementCnt[ele]].erase(cntToEle[elementCnt[ele]].find(ele));
        if(cntToEle[elementCnt[ele]].empty()) cntToEle.erase(elementCnt[ele]);
        if(cntToEle.find(elementCnt[ele] + 1) != cntToEle.end()){
            cntToEle[elementCnt[ele] + 1].insert(ele);
        }else{
            set<int> s;
            s.insert(ele);
            cntToEle[elementCnt[ele] + 1] = s;
        }
        elementCnt[ele]++;
    }else{
        elementCnt[ele]++;
        if(cntToEle.find(1) != cntToEle.end()){
            cntToEle[1].insert(ele);
        }else{
            set<int> s;
            s.insert(ele);
            cntToEle[1] = s;
        }
    }
}


vector<int> getMode(vector<int> &A, vector<vector<int> > &B) {
    unordered_map<int, int> elementCnt = buildElementCnt(A);
    map<int, set<int>> cntToEle = buildCntToEls(elementCnt);
    vector<int> ans;
    
    //perform update operation
    for(int i=0; i<B.size(); i++){
        
        removeEle(A[B[i][0]-1], elementCnt, cntToEle);
        addEle(B[i][1], elementCnt, cntToEle);
        A[B[i][0]] = B[i][1];
        ans.push_back(*(cntToEle.rbegin()->second).begin());
    }

    return ans;
}

int main() {
    vector<int> ar={2, 2, 2, 3, 3,5,5};
    vector<vector<int>> updates = {{1,3},{5,4},{2,4}};
    vector<int> ans = getMode(ar, updates);
    cout<<"value: ";
    for(int value: ans)cout<<value<<" ";
    return 0;
}

【讨论】:

  • 请提供文本以突出显示此代码与其他答案的不同之处。纯代码答案可能会被标记。我暂时对此投了反对票
【解决方案2】:
// this is classic implementation of LRU cache , I have used hash map and priority queue (heap to sort by frequency)    
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;

class Node implements Comparable<Node> {
    Integer key;
    Integer count;

    public Node(Integer key) {
        this.key = key;
        this.count = 1;

    }

    @Override
    public int compareTo(Node a) {
        return count != a.count ? a.count - count : key - a.key;
    }

}

public class Ninja1 {
    public static void main(String[] args) {
        Ninja1 n = new Ninja1();
        ArrayList<ArrayList<Integer>> b = new ArrayList<ArrayList<Integer>>();
        b.add(new ArrayList<Integer>(Arrays.asList(1, 3)));
        b.add(new ArrayList<Integer>(Arrays.asList(5, 4)));
        b.add(new ArrayList<Integer>(Arrays.asList(2, 4)));
        //b.add(new ArrayList<Integer>(Arrays.asList(1, 4)));
        System.out.println(n.getMode(new ArrayList<Integer>(Arrays.asList(2, 2, 2, 3, 3)), b));

    }

    public ArrayList<Integer> getMode(ArrayList<Integer> a, ArrayList<ArrayList<Integer>> b) {
        Queue<Node> q = new PriorityQueue<Node>();
        Map<Integer, Node> map = new HashMap<Integer, Node>();
        ArrayList<Integer> sol = new ArrayList<Integer>();

        Node temp = null;
        for (Integer i : a) {
            temp = map.get(i);
            if (temp == null) {
                Node n = new Node(i);
                map.put(i, n);
                q.add(n);
            } else {
                q.remove(temp);
                temp.count = temp.count + 1;
                q.add(temp);
            }
        }

        for (List<Integer> i : b) {
            if (a.get(i.get(0) - 1) != i.get(1)) {
                temp = map.get(a.get(i.get(0) - 1));
                q.remove(temp);

                if (temp.count != 1) {
                    temp.count = temp.count - 1;
                    q.add(temp);
                }

                temp = map.get(i.get(1));
                if (temp == null) {
                    Node n = new Node(i.get(1));
                    map.put(i.get(1), n);
                    q.add(n);
                } else {
                    q.remove(temp);
                    temp.count = temp.count + 1;
                    q.add(temp);
                }

            }
            sol.add(q.peek().key);
        }
        return sol;
    }
}

【讨论】:

  • 我建议您在答案中添加一些解释性文字,否则您可能会因为“低质量”而将其删除(即使它可能是正确的答案)!仅代码的答案通常会被标记为删除。
  • 这是 LRU 缓存的经典实现,我使用哈希映射和优先级队列(按频率排序的堆)来解决问题@Adrian,谢谢
【解决方案3】:

Java 解决方案:每次更新后更新元素并使用 hashMap 获取模式。 (虽然不是最优的)

public int[] getMode(int[] a, int[][] b) {
    int res[]=new int[b.length];
    int j=0;
    for(int i=0;i<b.length;i++)
    {
        int index=b[i][0];
        int element=b[i][1];
        a[index-1]=element;
        int m=mode(a);
        res[j]=m;
        j++;
    }
    return res;
}
public int mode(int[] a)
{
    HashMap<Integer,Integer> hm=new HashMap<Integer,Integer>();
    int max=0,m=0;
    for(int i=0;i<a.length;i++)
    {
        if(hm.containsKey(a[i]))
        {
            hm.put(a[i],hm.get(a[i])+1);
        }
        else
        {
            hm.put(a[i],1);
        }
        if(hm.get(a[i])>max)
        {
            max=hm.get(a[i]);
            m=a[i];
        }
        else if(hm.get(a[i])==max)
        {
            m=(m<a[i])?m:a[i];
        }
    }
    return m;
}

【讨论】:

    【解决方案4】:

    我在 C++ 中的回答:

    class compare
    {
        public:
        bool operator()(pair<int,int> p1,pair<int,int> p2)
        {
            if(p1.first==p2.first)
            return p1.second>p2.second;
            return p1.first<p2.first;
        }
    };
    vector<int> Solution::getMode(vector<int> &a, vector<vector<int> > &b) {
        map<int,int> m;// map store the exact count of elements
        int n=a.size();
        for(int i=0;i<n;i++)
        {
            m[a[i]]++;
        }
        vector<int> ans;
    
    // take a max heap which store element count and its value
        priority_queue<pair<int,int> ,vector<pair<int,int> >,compare >pq;
        for(int i=0;i<n;i++)
        {
            pq.push(make_pair(m[a[i]],a[i]));
        }
        int i=0,q=b.size();
        while(i<q)
        {
            int index=b[i][0]-1;
            int val=b[i][1];
            int val1=a[index];
            a[index]=val;
            if(val!=val1)
            {
                m[val1]--;
            m[val]++;
            pq.push(make_pair(m[val1],val1));
            pq.push(make_pair(m[val],val));
            }
            while(true)
            {
                pair<int,int> t=pq.top();
                int cnt=t.first;int vall=t.second;
                if(m[vall]==cnt)
                {
    
             // when top of heap has cnt same as in map then this the answer for the ith query
                    ans.push_back(vall);
                    break;
                }
                else
                pq.pop();
            }
            i++;
        }
        return ans;
    }
    

    【讨论】:

      【解决方案5】:

      我在 TreeMap 中使用 TreeMap,一个 TreeMap 用于按排序顺序存储模式,另一个 TreeMap 用于按排序顺序存储它们的频率。

      public class Solution {
          HashMap<Integer, Integer> map;
          TreeMap<Integer, TreeMap<Integer, Integer>> map2;
          public ArrayList<Integer> getMode(ArrayList<Integer> A, ArrayList<ArrayList<Integer>> B) {
              map = new HashMap<Integer, Integer>();
              map2 = new TreeMap<>();
              ArrayList<Integer> result = new ArrayList<Integer>();
      
              for(int i : A) {
                  if(map.containsKey(i))
                      map.put(i, map.get(i) +1);
                  else
                      map.put(i, 1);
              }
              for (Map.Entry m : map.entrySet()) {
                  int freq = (int)m.getValue();
                  TreeMap<Integer, Integer> x = new TreeMap<>();
                  if (map2.containsKey(freq) == true) {
                      x = map2.get(freq);
                  }
                  x.put((int)m.getKey(),1);
                  map2.put(freq, x);
              }
              for(ArrayList<Integer> update : B){
                  int index = update.get(0);
                  int num = update.get(1);
      
                  int toUpdate = A.get(index - 1);
      
                  if(map.get(toUpdate) != null) {
                      int freq = map.get(toUpdate);
                      TreeMap<Integer, Integer> temp = map2.get(freq);
                      if (temp.size() == 1) {
                          map2.remove(freq);
                      }
                      else {
                          temp.remove(toUpdate);
                          map2.put(freq, temp);
                      }
                      if (freq == 1) {
                          map.remove(toUpdate);
                      }
                      else {
                          map.put(toUpdate, freq - 1);
                          int z = freq-1;
                          TreeMap<Integer, Integer> tt = new TreeMap<>();
                          if (map2.containsKey(z)) {
                              tt = map2.get(z);
                          }
                          tt.put(toUpdate, 1);
                          map2.put(z, tt);
                      }
                  }
                  A.set(index - 1, num);
                  if(map.containsKey(num)) {
                      int tt = map.get(num);
                      TreeMap<Integer, Integer> w = map2.get(tt);
                      if (w.size() == 1) {
                          map2.remove(tt);
                      }
                      else {
                          w.remove(num);
                          map2.put(tt, w);
                      }
                      map.put(num, tt+1);
                      TreeMap<Integer, Integer> q = new TreeMap<>();
                      if (map2.containsKey(tt+1)) {
                          q = map2.get(tt+1);
                      }
                      q.put(num,1);
                      map2.put(tt+1, q);
                  }
                  else {
                      map.put(num, 1);
                      TreeMap<Integer, Integer> qq = new TreeMap<>();
                      if (map2.containsKey(1)) {
                          qq = map2.get(1);
                      }
                      qq.put(num, 1);
                      map2.put(1, qq);
                  }
                  int rr = (int)map2.lastKey();
                   TreeMap<Integer, Integer> xyz = map2.get(rr);
                  result.add((int)(xyz.firstKey()));
              }
              return result;
          }
      }
      

      【讨论】:

      • 欢迎来到 Stack Overflow!仅代码的答案不是很有帮助。请编辑您的答案,以解释您的代码解决原始问题的原因。
      【解决方案6】:
      My answer is in C++
              int getModeHash(unordered_map<int, int> &map)
              {
                  int maxCount = 0;
                  int maxCountNum = INT_MIN;
                  for ( auto it = map.begin(); it != map.end(); ++it)
                  {
                      if(maxCount <= it->second)
                      {
                          if(maxCount == it->second)
                          {
                              maxCountNum = min(maxCountNum, it->first);
                          }
                          else
                          {
                              maxCountNum = it->first;
                              maxCount = it->second;
                          }
                      }
                  }
                  return maxCountNum;
              }
              vector<int> Solution::getMode(vector<int> &A, vector<vector<int> > &B) {
                 unordered_map<int, int> map;
                 vector<int> result;
      
              //Store A array elements count in hash i.e.. map
                 for(int i=0; i< A.size(); i++)
                 {
                     if(map.find(A[i]) == map.end())
                     {
                         map[A[i]] = 0;
                     }
                     map[A[i]]++;
                 }
                 // now update hash map for each element in B, 
                 //and get large count element
                 for(int i=0; i < B.size(); i++)
                 {
                      map[A[B[i][0]-1]]--;
                      if(map[A[B[i][0]-1]] == 0)
                      {
                          map.erase(A[B[i][0]-1]);
                      }
                      A[B[i][0]-1] = B[i][1];
                     if(map.find(A[B[i][0]-1]) == map.end())
                     {
                         map[A[B[i][0]-1]] = 0;
                     }
                     map[A[B[i][0]-1]]++;     
      
                     result.push_back(getModeHash(map));
                 }
                 return result;
              }
      

      【讨论】:

        猜你喜欢
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        相关资源
        最近更新 更多