2628. 完全相等的 JSON 字符串 🔒
2628. 完全相等的 JSON 字符串 🔒
题目
Given two values o1
and o2
, return a boolean value indicating whether two values, o1
and o2
, are deeply equal.
For two values to be deeply equal , the following conditions must be met:
If both values are primitive types, they are deeply equal if they pass the
===
equality check.If both values are arrays, they are deeply equal if they have the same elements in the same order, and each element is also deeply equal according to these conditions.
If both values are objects, they are deeply equal if they have the same keys, and the associated values for each key are also deeply equal according to these conditions.
You may assume both values are the output of JSON.parse
. In other words, they are valid JSON.
Please solve it without using lodash's _.isEqual()
function
Example 1:
Input: o1 = {"x":1,"y":2}, o2 =
Output: true
Explanation: The keys and values match exactly.
Example 2:
Input: o1 = {"y":2,"x":1}, o2 =
Output: true
Explanation: Although the keys are in a different order, they still match exactly.
Example 3:
Input: o1 = {"x":null,"L":[1,2,3]}, o2 =
Output: false
Explanation: The array of numbers is different from the array of strings.
Example 4:
Input: o1 = true, o2 = false
Output: false
Explanation: true !== false
Constraints:
1 <= JSON.stringify(o1).length <= 10^5
1 <= JSON.stringify(o2).length <= 10^5
maxNestingDepth <= 1000
题目大意
给定两个对象 o1
和 o2
,请你检查它们是否 完全相等 。
对于两个 完全相等 的对象,必须满足以下条件:
- 如果两个值都是原始类型,它们通过了
===
等式检查,则认为这两个值是 完全相等 的。 - 如果两个值都是数组,在它们具有相同元素且顺序相同,并且每个元素在这些条件下也 **完全相等 **时,认为这两个值是 完全相等 的。
- 如果两个值都是对象,在它们具有相同键,并且每个键关联的值在这些条件下也 完全相等 时,认为这两个值是 完全相等 的。
你可以假设这两个对象都是 JSON.parse
的输出。换句话说,它们是有效的 JSON
。
请你在不使用 lodash 的 _.isEqual()
函数的前提下解决这个问题。
示例 1:
输入: o1 = {"x":1,"y":2}, o2 =
输出: true
输入: 键和值完全匹配。
示例 2:
输入: o1 = {"y":2,"x":1}, o2 =
输出: true
解释: 尽管键的顺序不同,但它们仍然完全匹配。
示例 3:
输入: o1 = {"x":null,"L":[1,2,3]}, o2 =
输出: false
解释: 数字数组不同于字符串数组。
示例 4:
输入: o1 = true, o2 = false
输出: false
解释: true !== false
提示:
1 <= JSON.stringify(o1).length <= 10^5
1 <= JSON.stringify(o2).length <= 10^5
maxNestingDepth <= 1000
解题思路
主要的难点在于对比深层嵌套的对象和数组时,需要递归调用比较函数:
类型检查:
- 首先检查两个值是否都是
null
或者都是对象。如果其中一个是null
而另一个不是,则返回false
。
- 首先检查两个值是否都是
原始类型比较:
- 如果两个值都是原始类型(如数字、字符串等),则使用
===
进行比较。
- 如果两个值都是原始类型(如数字、字符串等),则使用
数组和对象比较:
- 如果两个值都是数组,则比较它们的长度并递归比较每个元素。
- 如果两个值都是对象,则比较它们的键数、键的名称以及每个键对应的值。
递归调用:
- 对于每个需要深入比较的值,递归调用比较函数。
复杂度分析
- 时间复杂度:
O(n)
,其中n
是两个对象的元素总数,因为每个元素都需要被比较。 - 空间复杂度:
O(d)
,其中d
是嵌套的最大深度,主要取决于递归的深度。
代码
var areDeeplyEqual = function (o1, o2) {
// 检查 null 和原始类型
if (o1 === o2) return true; // 同时为 null 或相同原始类型
if (
o1 === null ||
o2 === null ||
typeof o1 !== 'object' ||
typeof o2 !== 'object'
)
return false;
// 检查是否为数组
if (Array.isArray(o1) !== Array.isArray(o2)) return false;
// 获取对象的键
let keys1 = Object.keys(o1),
keys2 = Object.keys(o2);
// 检查键的数量
if (keys1.length !== keys2.length) return false;
// 递归比较每个键的值
for (let key of keys1) {
// 递归调用
if (!areDeeplyEqual(o1[key], o2[key])) return false;
}
return true;
};
相关题目
题号 | 标题 | 题解 | 标签 | 难度 |
---|---|---|---|---|
2625 | 扁平化嵌套数组 | [✓] | ||
2633 | 将对象转换为 JSON 字符串 🔒 | [✓] | ||
2675 | 将对象数组转换为矩阵 🔒 | [✓] | ||
2700 | 两个对象之间的差异 🔒 |