哈希映射,用 slice(start, end) / array_slice(start, length) / List.subList(start, end) / IList.Skip(start).Take(length).ToList() 分割数组,求解《1282. 用户分组》

1282. 用户分组

有 n 个人被分成数量未知的组。每个人都被标记为一个从 0 到 n - 1 的唯一ID 。
给定一个整数数组 groupSizes ,其中 groupSizes[i] 是第 i 个人所在的组的大小。例如,如果 groupSizes[1] = 3 ,则第 1 个人必须位于大小为 3 的组中。
返回一个组列表,使每个人 i 都在一个大小为 groupSizes[i] 的组中。
每个人应该 恰好只 出现在 一个组 中,并且每个人必须在一个组中。如果有多个答案,返回其中 任何 一个。可以 保证 给定输入 至少有一个 有效的解。
示例 1:
输入:groupSizes = [3,3,3,3,3,1,3]
输出:[[5],[0,1,2],[3,4,6]]
解释:
第一组是 [5],大小为 1,groupSizes[5] = 1。
第二组是 [0,1,2],大小为 3,groupSizes[0] = groupSizes[1] = groupSizes[2] = 3。
第三组是 [3,4,6],大小为 3,groupSizes[3] = groupSizes[4] = groupSizes[6] = 3。
其他可能的解决方案有 [[2,1,6],[5],[0,4,3]] 和 [[5],[0,6,2],[4,3,1]]。

答案

哈希映射

var groupThePeople = function(groupSizes) { // Object.create(null)
  const n = groupSizes.length, r = Object.create(null)
  for (let i = 0; i < n; i++) {
    const groupSize = groupSizes[i]
    if (r[groupSize] === void 0) r[groupSize] = [[]]
    const t = r[groupSize]
    if (t[t.length - 1].length === groupSize) t.push([])
    t[t.length - 1].push(i)
  }
  return Object.values(r).flat()
};
function groupThePeople(groupSizes: number[]): number[][] {
  const n = groupSizes.length, h = new Map, r = []
  for (let i = 0; i < n; i++) {
    const groupSize = groupSizes[i]
    if (h.has(groupSize) === false) h.set(groupSize, [])
    h.get(groupSize).push(i)
  }
  for (const [groupSize, people] of h.entries()) {
    const m = people.length / groupSize
    for (let i = 0; i < m; i++) {
      r.push(people.slice(i * groupSize, (i + 1) * groupSize))
    }
  }
  return r
};
class Solution {
  function groupThePeople($groupSizes) {
    $h = array();
    $r = array();
    foreach($groupSizes as $i => $groupSize) {
      if ($h[$groupSize] === null) $h[$groupSize] = [];
      $h[$groupSize] []= $i;
    }
    foreach ($h as $groupSize => $people) {
      $m = count($people) / $groupSize;
      for ($i = 0; $i < $m; $i++) {
        $r []= array_slice($people, $i * $groupSize, $groupSize);
      }
    }
    return $r;
  }
}
func groupThePeople(groupSizes []int) [][]int {
  h, r := make(map[int][]int), [][]int{}
  for i, groupSize := range groupSizes {
    _, ok := h[groupSize]
    if ok == false {
      h[groupSize] = []int{}
    }
    h[groupSize] = append(h[groupSize], i)
  }
  for groupSize, people := range h {
    m := len(people) / groupSize
    for i := 0; i < m; i++ {
      r = append(r, people[i * groupSize : (i + 1) * groupSize])
    }
  }
  return r;
}
class Solution {
  public List<List<Integer>> groupThePeople(int[] groupSizes) {
    int n = groupSizes.length;
    Map<Integer, List<Integer>> h = new HashMap<Integer, List<Integer>>();
    for (int i = 0; i < n; i++) {
      int groupSize = groupSizes[i];
      if (h.containsKey(groupSize) == false) h.put(groupSize, new ArrayList<Integer>());
      h.get(groupSize).add(i);
    }
    List<List<Integer>> r = new ArrayList<List<Integer>>();
    for (Map.Entry<Integer, List<Integer>> entry : h.entrySet()) {
      Integer groupSize = entry.getKey();
      List<Integer> people = entry.getValue();
      int m = people.size() / groupSize;
      for (int i = 0; i < m; i++) {
        r.add(people.subList(i * groupSize, (i + 1) * groupSize));
      }
    }
    return r;
  }
}
public class Solution {
  public IList<IList<int>> GroupThePeople(int[] groupSizes) {
    int n = groupSizes.Length;
    Dictionary<int, IList<int>> h = new Dictionary<int, IList<int>>();
    for (int i = 0; i < n; i++) {
      int groupSize = groupSizes[i];
      if (h.ContainsKey(groupSize) == false) h.Add(groupSize, new List<int>());
      h[groupSize].Add(i);
    }
    IList<IList<int>> r = new List<IList<int>>();
    foreach(KeyValuePair<int, IList<int>> pair in h) {
      int groupSize = pair.Key;
      IList<int> people = pair.Value;
      int m = people.Count / groupSize;
      for (int i = 0; i < m; i++) {
        IList<int> t = people.Skip(i * groupSize).Take(groupSize).ToList();
        r.Add(t);
      }
    }
    return r;
  }
}
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
typedef struct Array {
  int* ar;
  int pos;
  int size;
} Array;

Array* newArray(int size) {
  Array* obj = malloc(sizeof(Array));
  obj->ar = malloc(sizeof(int) * size);
  obj->size = size;
  obj->pos = 0;
  return obj;
}

void freeArray(Array* obj) {
  free(obj->ar);
  free(obj);
}

int** groupThePeople(int* groupSizes, int groupSizesSize, int* returnSize, int** returnColumnSizes){
  Array** h = malloc(sizeof(Array*) * (groupSizesSize + 1));
  for (int i = 0; i <= groupSizesSize; i++) {
    h[i] = newArray(groupSizesSize);
  }
  for (int i = 0; i < groupSizesSize; i++) {
    int groupSize = groupSizes[i];
    Array* t = h[groupSize];
    t->ar[t->pos++] = i;
  }
  int** r = malloc(sizeof(int*) * groupSizesSize);
  int pos = 0;
  *returnColumnSizes = malloc(sizeof(int) * groupSizesSize);
  for (int i = 0; i <= groupSizesSize; i++) {
    if (h[i]->pos == 0) continue;
    int groupSize = i;
    int* people = h[i]->ar;
    int size = h[i]->pos;
    int m = size / groupSize;
    for (int j = 0; j < m; j++) {
      int* t = malloc(sizeof(int) * groupSize);
      for (int k = 0; k < groupSize; k++) {
        t[k] = people[j * groupSize + k];
      }
      (*returnColumnSizes)[pos] = groupSize;
      r[pos++] = t;
    }
  }
  *returnSize = pos;
  for (int i = 0; i <= groupSizesSize; i++) {
    freeArray(h[i]);
  }
  return r;
}
class Solution {
public:
  vector<vector<int>> groupThePeople(vector<int>& groupSizes) {
    unordered_map<int, vector<int>> h;
    int n = groupSizes.size();
    for (int i = 0; i < n; i++) {
      int groupSize = groupSizes[i];
      h[groupSize].push_back(i);
    }
    vector<vector<int>> r;
    for (auto &[groupSize, people] : h) {
      int m = people.size() / groupSize;
      for (int i = 0; i < m; i++) {
        vector<int> t(groupSize);
        for (int j = 0; j < groupSize; j++) {
          t[j] = people[i * groupSize + j];
        } 
        r.push_back(t);
      }
    }
    return r;
  }
};
class Solution:
  def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]:
    h, r = defaultdict(list), [] # 键值字典 -> 键列表字典
    for i, groupSize in enumerate(groupSizes): h[groupSize].append(i)
    for groupSize, people in h.items():
      r.extend(people[i: i + groupSize] for i in range(0, len(people), groupSize))
    return r

自定义排序,二分查找(upper_bound / lower_bound + 双指针 / 传递回调函数)2 算法 4 解法,slice / array_slice / subList / Arrays.copyOfRange / GetRange / memcpy 截取列表,求解《658. 找到 K 个最接近的元素》
自定义排序,二分查找(upper_bound / lower_bound + 双指针 / 直接找左边界)2 算法 4 解法,slice / array_slice / subList / Arrays.copyOfRange / GetRange / memcpy 截取列表,传递函数,求解《658. 找到 K 个最接近的元素》
哈希表(用 uthash / Dictionary / dict / HashMap / unordered_map 等 + 定长列表实现),排序 + 拼接字符串 2 算法,求解《1460. 通过翻转子数组使两个数组相等》
哈希表(用 uthash / Dictionary / dict / HashMap / unordered_map 等 + 定长列表实现),排序 + 拼接字符串 2 算法,用 join / implode / fmt.Sprint 将列表转字符串比较,用 Array.equals / (int[]).SequenceEqual 比较列表,C++ 直接比较 vector&……
递归和单调递减栈 2 算法,用 数组 / Slice / ArrayDeque / Stack / int* / stack / vector / List 实现,求解《654. 最大二叉树》
递归和单调递减栈 2 算法,用 数组 / Slice / ArrayDeque / Stack / int* / stack / vector / List 实现,求解《654. 最大二叉树》