哈希表(用 uthash / Dictionary / dict / HashMap / unordered_map 等 + 定长列表实现),排序 + 拼接字符串 2 算法,求解《1460. 通过翻转子数组使两个数组相等》

2022-08-24 14:44:50

哈希表(用 uthash / Dictionary / dict / HashMap / unordered_map 等 + 定长列表实现),排序 + 拼接字符串 2 算法,用 join / implode / fmt.Sprint 将列表转字符串比较,用 Array.equals / (int[]).SequenceEqual 比较列表,C++ 直接比较 vector<int>,Python 直接比较 List[int],求解《1460. 通过翻转子数组使两个数组相等》

例题

1460. 通过翻转子数组使两个数组相等

给你两个长度相同的整数数组 target 和 arr 。每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转。你可以执行此过程任意次。
如果你能让 arr 变得与 target 相同,返回 True;否则,返回 False 。
示例 1:
输入:target = [1,2,3,4], arr = [2,4,1,3]
输出:true
解释:你可以按照如下步骤使 arr 变成 target:
1- 翻转子数组 [2,4,1] ,arr 变成 [1,4,2,3]
2- 翻转子数组 [4,2] ,arr 变成 [1,2,4,3]
3- 翻转子数组 [4,3] ,arr 变成 [1,2,3,4]
上述方法并不是唯一的,还存在多种将 arr 变成 target 的方法。
示例 2: 输入:target = [7], arr = [7]
输出:true
解释:arr 不需要做任何翻转已经与 target 相等。
示例 3:
输入:target = [3,7,9], arr = [3,7,11]
输出:false
解释:arr 没有数字 9 ,所以无论如何也无法变成 target 。
提示:
target.length == arr.length
1 <= target.length <= 1000
1 <= target[i] <= 1000
1 <= arr[i] <= 1000

答案

哈希表

var canBeEqual = function(target, arr) { // Map 实现
  const h = new Map, n = target.length
  for (let i = 0; i < n; i++) {
    h.set(target[i], (h.get(target[i]) || 0) + 1)
    h.set(arr[i], (h.get(arr[i]) || 0) - 1)
  }
  for (const v of h.values()) {
    if (v !== 0) return false
  }
  return true
};
var canBeEqual = function(target, arr) { // Object 实现
  const h = Object.create(null), n = target.length
  for (let i = 0; i < n; i++) {
    h[target[i]] = (h[target[i]] || 0) + 1
    h[arr[i]] = (h[arr[i]] || 0) - 1
  }
  const values = Object.values(h), m = values.length
  for (let i = 0; i < m; i++) {
    if (values[i] !== 0) return false
  }
  return true
};
var canBeEqual = function(target, arr) { // Array 实现
  const n = target.length, h = new Int16Array(1001)
  for (let i = 0; i < n; i++) {
    h[target[i]]++;
    h[arr[i]]--;
  }
  for (let i = 1; i < 1001; i++) {
    if (h[i] !== 0) return false
  }
  return true
};
function canBeEqual(target: number[], arr: number[]): boolean {
  const h = new Int16Array(1001), n = target.length
  for (let i = 0; i < n; i++) {
    h[target[i]]++
    h[arr[i]]--
  }
  for (let i = 1; i < 1001; i++) {
    if (h[i] !== 0) return false
  }
  return true
};
class Solution {
  function canBeEqual($target, $arr) {
    $h = array_fill(1, 1001, 0);
    foreach ($target as $i => $t) {
      $h[$t]++;
      $h[$arr[$i]]--;
    }
    for ($i = 1; $i < 1001; $i++) {
      if ($h[$i] !== 0) return false;
    }
    return true;
  }
}
func canBeEqual(target []int, arr []int) bool {
  h := map[int]int{}
  for i, t := range target {
    h[t]++
    h[arr[i]]--
  }
  for _, v := range h {
    if v != 0 {
      return false
    }
  }
  return true
}
class Solution { // Map 实现
  public boolean canBeEqual(int[] target, int[] arr) {
    Map<Integer, Integer> h = new HashMap<Integer, Integer>();
    int n = target.length;
    for (int i = 0; i < n; i++) {
      h.put(target[i], h.getOrDefault(target[i], 0) + 1);
      h.put(arr[i], h.getOrDefault(arr[i], 0) - 1);
    }
    for (int v : h.values()) {
      if (v != 0) return false;
    }
    return true;
  }
}
class Solution { // int[] 实现
  public boolean canBeEqual(int[] target, int[] arr) {
    int[] h = new int[1001];
    int n = target.length;
    for (int i = 0; i < n; i++) {
      h[target[i]]++;
      h[arr[i]]--;
    }
    for (int i = 1; i < 1001; i++) {
      if (h[i] != 0) return false;
    }
    return true;
  }
}
public class Solution { // Dictionary 实现
  public bool CanBeEqual(int[] target, int[] arr) {
    Dictionary<int, int> h = new Dictionary<int, int>();
    int n = target.Length;
    for (int i = 0; i < n; i++) {
      if (h.ContainsKey(target[i])) h[target[i]]++;
      else h.Add(target[i], 1);
      if (h.ContainsKey(arr[i])) h[arr[i]]--;
      else h.Add(arr[i], -1);
    }
    foreach (int value in h.Values) {
      if (value != 0) return false;
    }
    return true;
  }
}
public class Solution { // int[] 实现
  public bool CanBeEqual(int[] target, int[] arr) {
    int[] h = new int[1001];
    int n = target.Length;
    for (int i = 0; i < n; i++) {
      h[target[i]]++;
      h[arr[i]]--;
    }
    for (int i = 1; i < 1001; i++) {
      if (h[i] != 0) return false;
    }
    return true;
  }
}
typedef struct { // uthash 实现
  int key;
  int val;
  UT_hash_handle hh;
} HashItem;
bool canBeEqual(int* target, int targetSize, int* arr, int arrSize){
  HashItem* h = NULL;
  for (int i = 0; i < targetSize; i++) {
    HashItem* pEntry = NULL;
    HASH_FIND_INT(h, &target[i], pEntry);
    if (pEntry == NULL) {
      pEntry = malloc(sizeof(HashItem));
      pEntry->key = target[i];
      pEntry->val = 1;
      HASH_ADD_INT(h, key, pEntry);
    } else {
      pEntry->val++;
    }
    pEntry = NULL;
    HASH_FIND_INT(h, &arr[i], pEntry);
    if (pEntry == NULL) {
      pEntry = malloc(sizeof(HashItem));
      pEntry->key = arr[i];
      pEntry->val = -1;
      HASH_ADD_INT(h, key, pEntry);
    } else {
      pEntry->val--;
    }
  }
  HashItem* pEntry = NULL, *tmp;
  HASH_ITER(hh, h, pEntry, tmp) {
    if (pEntry->val != 0) {
      free(h);
      return false;
    } 
  }
  free(h);
  return true;
}
bool canBeEqual(int* target, int targetSize, int* arr, int arrSize){ // int* 实现
  int* h = malloc(sizeof(int) * 1001);
  memset(h, 0, sizeof(int) * 1001);
  for (int i = 0; i < targetSize; i++) {
    h[target[i]]++;
    h[arr[i]]--;
  }
  for (int i = 1; i < 1001; i++) {
    if (h[i] != 0) return false;
  }
  return true;
}
class Solution { // unodered_map 实现 unodered_map<key, T>::iterator 遍历
public:
  bool canBeEqual(vector<int>& target, vector<int>& arr) {
    unordered_map<int, int> h;
    int n = target.size();
    for (int i = 0; i < n; i++) {
      if (h.find(target[i]) == h.end()) h.emplace(target[i], 1);
      else h[target[i]]++;
      if (h.find(arr[i]) == h.end()) h.emplace(arr[i], -1);
      else h[arr[i]]--;
    }
    for (unordered_map<int, int>::iterator iter = h.begin(); iter != h.end(); ++iter) {
      if (iter->second != 0) return false;
    }
    return true;
  }
};
class Solution { // unodered_map 实现 for pair 遍历
public:
  bool canBeEqual(vector<int>& target, vector<int>& arr) {
    unordered_map<int, int> h;
    int n = target.size();
    for (int i = 0; i < n; i++) {
      if (h.find(target[i]) == h.end()) h.emplace(target[i], 1);
      else h[target[i]]++;
      if (h.find(arr[i]) == h.end()) h.emplace(arr[i], -1);
      else h[arr[i]]--;
    }
    for (pair<int, int> iter: h) {
      if (iter.second != 0) return false;
    }
    return true;
  }
};
class Solution: # dict 实现
  def canBeEqual(self, target: List[int], arr: List[int]) -> bool:
    h = dict()
    for i, t in enumerate(target):
      h[t] = h.get(t, 0) + 1
      h[arr[i]] = h.get(arr[i], 0) - 1
    for value in h.values():
      if value != 0: return False
    return True
class Solution: # list 实现
  def canBeEqual(self, target: List[int], arr: List[int]) -> bool:
    h = [0] * 1001
    for i, t in enumerate(target):
      h[t] += 1
      h[arr[i]] -= 1
    for i in range(1, 1001):
      if h[i] != 0: return False
    return True

排序 · 升序 · 拼接字符串

var canBeEqual = function(target, arr) {
  return target.sort().join('') === arr.sort().join('') // 转字符串比较
};
function canBeEqual(target: number[], arr: number[]): boolean {
  return target.sort().join('') === arr.sort().join('') // 转字符串比较
};
class Solution {
  function canBeEqual($target, $arr) {
    sort($target, SORT_NUMERIC);
    sort($arr, SORT_NUMERIC);
    return implode('', $target) === implode('', $arr); // 转字符串比较
  }
}
func canBeEqual(target []int, arr []int) bool {
  sort.Ints(target)
  sort.Ints(arr)
  return fmt.Sprint(target) == fmt.Sprint(arr) // 转字符串比较
}
class Solution {
  public boolean canBeEqual(int[] target, int[] arr) {
    Arrays.sort(target);
    Arrays.sort(arr);
    return Arrays.equals(target, arr); // 列表比较
  }
}
public class Solution {
  public bool CanBeEqual(int[] target, int[] arr) {
    Array.Sort(target);
    Array.Sort(arr);
    return target.SequenceEqual(arr); // 列表比较
  }
}
static inline int cmp(const void *pa, const void *pb) {
  return *(int *)pa - *(int *)pb;
}
bool canBeEqual(int* target, int targetSize, int* arr, int arrSize){
  qsort(target, targetSize, sizeof(int), cmp);
  qsort(arr, arrSize, sizeof(int), cmp);
  return memcmp(target, arr, sizeof(int) * targetSize) == 0; // 内存比较
}
class Solution {
public:
  bool canBeEqual(vector<int>& target, vector<int>& arr) {
    sort(target.begin(), target.end());
    sort(arr.begin(), arr.end());
    return target == arr; // 直接比较
  }
};
class Solution:
  def canBeEqual(self, target: List[int], arr: List[int]) -> bool:
    return sorted(target) == sorted(arr) // 直接比较

顺序遍历 + 拼接字符串,倒序遍历 + 顺序遍历 + 双指针,repeat / str_repeat / strings.Repeat / new string() / string / * 重复字符串,join / implode / accumulate 数组列表转字符串,2 解法求解《1592. 重新排列单词间的空格》
顺序遍历 + 拼接字符串,倒序遍历 + 顺序遍历 + 双指针,repeat / str_repeat / strings.Repeat / new string() / string / * 重复字符串,join / implode / accumulate 数组列表转字符串,2 解法求解《1592. 重新排列单词间的空格》
迭代遍历哈希表,求解《828. 统计子串中的唯一字符》
迭代遍历哈希表,求解《828. 统计子串中的唯一字符》
后序遍历,递归和迭代 2 种算法,用哈希映射数据结构,字符串或元组构造键名,用序列化技巧,求解《652. 寻找重复的子树》
后序遍历,递归和迭代 2 种算法,用哈希映射数据结构,字符串 / 元组构造键名,用序列化技巧,求解《652. 寻找重复的子树》