fastest algorithm count number of 3 length AP in array

后端 未结 2 1763
陌清茗
陌清茗 2021-01-03 15:24

I want to solve this CodeChef challenge:

Suppose We are given an array A of N(of range 100,000) elements. We are to find the count of all pairs of 3 such elements 1&

2条回答
  •  难免孤独
    2021-01-03 15:54

    You can greatly cut execution time if you make a first pass over the list and only extract number pairs that it is possible to have an 3 term AP between (difference is 0 mod 2). And then iterating between such pairs.

    Pseudo C++-y code:

    // Contains information about each beginning point
    struct BeginNode {
      int value;
      size_t offset;
      SortedList ends;  //sorted by EndNode.value
    };
    
    // Contains information about each class of end point
    struct EndNode {
      int value;
      List offsets; // will be sorted without effort due to how we collect offsets
    };
    
    struct Result {
      size_t begin;
      size_t middle;
      size_t end;
    };
    
    SortedList nodeList;
    foreach (auto i : baseList) {
      BeginNode begin;
      node.value = i;
      node.offset = i's offset; //you'll need to use old school for (i=0;etc;i++) with this
      // baseList is the list between begin and end-2 (inclusive)
      foreach (auto j : restList) { 
        // restList is the list between iterator i+2 and end (inclusive)
        // we do not need to consider i+1, because not enough space for AP
        if ((i-j)%2 == 0) { //if it's possible to have a 3 term AP between these two nodes
          size_t listOffset = binarySearch(begin.ends);
          if (listOffset is valid) {
            begin.ends[listOffset].offsets.push_back(offsets);
          } else {
            EndNode end;
            end.value = j;
            end.offsets.push_back(j's offset);
            begin.ends.sorted_insert(end);
          }
        }
      }
      if (begin has shit in it) {
        nodeList.sorted_insert(begin);
      }
    }
    // Collection done, now iterate over collection
    
    List res;
    foreach (auto node : nodeList) {
      foreach (auto endNode : node.ends) {
        foreach (value : sublist from node.offset until endNode.offsets.last()) {
          if (value == average(node.value, endNode.value)) {
            // binary_search here to determine how many offsets in "endNode.offsets" "value's offset" is less than.
            do this that many times:
              res.push_back({node.value, value, endNode.value});
          }
        }
      }
    }
    
    return res;
    

提交回复
热议问题