跳至主要內容

2628. 完全相等的 JSON 字符串 🔒


2628. 完全相等的 JSON 字符串 🔒open in new window

🟠   🔗 力扣open in new window LeetCodeopen in new window

题目

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

题目大意

给定两个对象 o1o2 ,请你检查它们是否 完全相等

对于两个 完全相等 的对象,必须满足以下条件:

  • 如果两个值都是原始类型,它们通过了 === 等式检查,则认为这两个值是 完全相等 的。
  • 如果两个值都是数组,在它们具有相同元素且顺序相同,并且每个元素在这些条件下也 **完全相等 **时,认为这两个值是 完全相等 的。
  • 如果两个值都是对象,在它们具有相同键,并且每个键关联的值在这些条件下也 完全相等 时,认为这两个值是 完全相等 的。

你可以假设这两个对象都是 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

解题思路

主要的难点在于对比深层嵌套的对象和数组时,需要递归调用比较函数:

  1. 类型检查

    • 首先检查两个值是否都是 null 或者都是对象。如果其中一个是 null 而另一个不是,则返回 false
  2. 原始类型比较

    • 如果两个值都是原始类型(如数字、字符串等),则使用 === 进行比较。
  3. 数组和对象比较

    • 如果两个值都是数组,则比较它们的长度并递归比较每个元素。
    • 如果两个值都是对象,则比较它们的键数、键的名称以及每个键对应的值。
  4. 递归调用

    • 对于每个需要深入比较的值,递归调用比较函数。

复杂度分析

  • 时间复杂度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扁平化嵌套数组open in new window[✓]
2633将对象转换为 JSON 字符串 🔒open in new window[✓]
2675将对象数组转换为矩阵 🔒open in new window[✓]
2700两个对象之间的差异 🔒open in new window