顺序遍历,哈希映射,2 解法求解《1640. 能否连接形成数组》

例题

1640. 能否连接形成数组

给你一个整数数组 arr ,数组中的每个整数 互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也 互不相同 。请你以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组 pieces[i] 中的整数重新排序。
如果可以连接 pieces 中的数组形成 arr ,返回 true ;否则,返回 false 。
示例 1:
输入:arr = [15,88], pieces = [[88],[15]]
输出:true
解释:依次连接 [15] 和 [88]
示例 2:
输入:arr = [49,18,16], pieces = [[16,18,49]]
输出:false
解释:即便数字相符,也不能重新排列 pieces[0]
示例 3:
输入:arr = [91,4,64,78], pieces = [[78],[4,64],[91]]
输出:true
解释:依次连接 [91]、[4,64] 和 [78]
提示:
1 <= pieces.length <= arr.length <= 100
sum(pieces[i].length) == arr.length
1 <= pieces[i].length <= arr.length
1 <= arr[i], pieces[i][j] <= 100
arr 中的整数 互不相同
pieces 中的整数 互不相同(也就是说,如果将 pieces 扁平化成一维数组,数组中的所有整数互不相同)

答案

顺序遍历
var canFormArray = function(arr, pieces) {
  const n = arr.length, m = pieces.length
  label: for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (pieces[j][0] !== arr[i]) continue
      for (let k = 1; k < pieces[j].length; k++) {
        if (pieces[j][k] !== arr[i + 1]) return false
        i++
      }
      continue label 
    }
    return false
  }
  return true
};
哈希映射

var canFormArray = function(arr, pieces) {
  const n = arr.length, m = pieces.length, h = new Map
  for (let i = 0; i < m; i++) h.set(pieces[i][0], i)
  for (let i = 0; i < n; i++) {
    if (h.has(arr[i]) === false) return false
    const piece = pieces[h.get(arr[i])], l = piece.length
    for (let j = 1; j < l; j++) if (piece[j] !== arr[++i]) return false
  }
  return true
};
function canFormArray(arr: number[], pieces: number[][]): boolean {
  const n = arr.length, h = new Map
  for (const [i, piece] of pieces.entries()) h.set(piece[0], i)
  for (let i = 0; i < n; i++) {
    if (h.has(arr[i]) === false) return false
    const piece = pieces[h.get(arr[i])], m = piece.length
    for (let j = 1; j < m; j++) if (piece[j] !== arr[++i]) return false
  }
  return true
};
class Solution {
  function canFormArray($arr, $pieces) {
    $n = count($arr);
    $h = [];
    foreach ($pieces as $i => $piece) $h[$piece[0]] = $i;
    for ($i = 0; $i < $n; $i++) {
      if ($h[$arr[$i]] === null) return false;
      $piece = $pieces[$h[$arr[$i]]];
      $m = count($piece);
      for ($j = 1; $j < $m; $j++) {
        if ($piece[$j] !== $arr[++$i]) return false;
      }
    }
    return true;
  }
}
func canFormArray(arr []int, pieces [][]int) bool {
  n, h := len(arr), map[int]int{}
  for i, piece := range pieces {
    h[piece[0]] = i
  }
  for i := 0; i < n; i++ {
    index, ok := h[arr[i]]
    if ok == false {
      return false
    }
    piece := pieces[index]
    for j, m := 1, len(piece); j < m; j++ {
      if piece[j] != arr[i + 1] {
        return false
      }
      i++
    }
  }
  return true
}
class Solution {
  public boolean canFormArray(int[] arr, int[][] pieces) {
    int n = arr.length, m = pieces.length;
    Map<Integer, Integer> h = new HashMap<Integer, Integer>();
    for (int i = 0; i < m; i++) h.put(pieces[i][0], i);
    for (int i = 0; i < n; i++) {
      if (h.containsKey(arr[i]) == false) return false;
      int[] piece = pieces[h.get(arr[i])];
      int l = piece.length;
      for (int j = 1; j < l; j++) if (piece[j] != arr[++i]) return false;
    }
    return true;
  }
}
public class Solution {
  public bool CanFormArray(int[] arr, int[][] pieces) {
    int n = arr.Length, m = pieces.Length;
    Dictionary<int, int> h = new Dictionary<int, int>();
    for (int i = 0; i < m; i++) h.Add(pieces[i][0], i);
    for (int i = 0; i < n; i++) {
      if (h.ContainsKey(arr[i]) == false) return false;
      int[] piece = pieces[h[arr[i]]];
      int l = piece.Length;
      for (int j = 1; j < l; j++) if (piece[j] != arr[++i]) return false;
    }
    return true;
  }
}
typedef struct {
  int key;
  int val;
  UT_hash_handle hh;
} HashItem;
bool canFormArray(int* arr, int arrSize, int** pieces, int piecesSize, int* piecesColSize){
  HashItem* h = NULL;
  for (int i = 0; i < piecesSize; i++) {
    HashItem* pEntry = malloc(sizeof(HashItem));
    pEntry->key = pieces[i][0];
    pEntry->val = i;
    HASH_ADD_INT(h, key, pEntry);
  }
  for (int i = 0; i < arrSize; i++) {
    HashItem* pEntry = NULL;
    HASH_FIND_INT(h, &arr[i], pEntry);
    if (pEntry == NULL) return false;
    int* piece = pieces[pEntry->val];
    int m = piecesColSize[pEntry->val];
    for (int j = 1; j < m; j++) {
      if (piece[j] != arr[++i]) return false;
    }
  }
  HashItem *cur, *tmp;
  HASH_ITER(hh, h, cur, tmp) {
    HASH_DEL(h, cur);
    free(cur);
  }
  return true;
}
bool canFormArray(int* arr, int arrSize, int** pieces, int piecesSize, int* piecesColSize){
  int* h = malloc(sizeof(int) * 101);
  memset(h, -1, sizeof(int) * 101);
  for (int i = 0; i < piecesSize; i++) h[pieces[i][0]] = i;
  for (int i = 0; i < arrSize; i++) {
    if (h[arr[i]] == -1) return false;
    int* piece = pieces[h[arr[i]]];
    int m = piecesColSize[h[arr[i]]];
    for (int j = 1; j < m; j++) {
      if (piece[j] != arr[++i]) return false;
    }
  }
  return true;
}
class Solution {
public:
  bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
    int n = arr.size(), m = pieces.size();
    unordered_map<int, int> h;
    for (int i = 0; i < m; i++) h[pieces[i][0]] = i;
    for (int i = 0; i < n; i++) {
      if (h.find(arr[i]) == h.end()) return false;
      vector<int>& piece = pieces[h[arr[i]]];
      int l = piece.size();
      for (int j = 1; j < l; j++) if (piece[j] != arr[++i]) return false;
    }
    return true;
  }
};
class Solution:
  def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool:
    h, i = {piece[0]: i for i, piece in enumerate(pieces)}, 0
    while i < len(arr):
      if arr[i] not in h: return False
      piece = pieces[h[arr[i]]]
      for j in range(1, len(piece)):
        if piece[j] != arr[i + 1]: return False
        i += 1
      i += 1
    return True
class Solution:
  def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool:
    h, i = {piece[0]: i for i, piece in enumerate(pieces)}, 0
    while i < len(arr):
      if arr[i] not in h: return False
      piece = pieces[h[arr[i]]]
      l = len(piece)
      if arr[i : i + l] != piece: return False
      i += l
    return True

顺序遍历,动态规划(单变量空间压缩),求解《1800. 最大升序子数组和》
顺序遍历,动态规划(单变量空间压缩),2 种思想,归于 1 种解法,求解《1800. 最大升序子数组和》
顺序遍历,数组求和,求解《927. 三等分》
顺序遍历,数组求和,求解《927. 三等分》
用哈希映射数据结构,分割字符串为数组,截取字符串,求解《811. 子域名访问计数》
用哈希映射数据结构,用 split / explode / stirngs.Split / strtok 分割字符串为数组,substring / substr / 指针截取字符串,求解《811. 子域名访问计数》