Leetcode -1609.奇偶树
質問: 二分木が次の条件を満たす場合、それは奇数偶数木と呼ぶことができます。
バイナリ ツリーのルート ノードのレベル添字は 0、ルートの子ノードのレベル添字は 1、ルートの孫ノードのレベル添字は 2 などとなります。
偶数添字層のすべてのノードの値は奇数の整数であり、左から右の順序で厳密に増加します。
奇数添字層のすべてのノードの値は偶数の整数で、左から右の順序で厳密に減少します。
バイナリ ツリーを提供します。ルート ノードは、バイナリ ツリーが奇数偶数ツリーの場合は true を返し、それ以外の場合は false を返します。
例1:
入力: root = [1, 10, 4, 3, null, 7, 9, 12, 8, 6, null, null, 2] 出力: true 説明: 各レイヤーのノード値は次のとおり
です。 0:[1]レベル1:[10, 4]レベル2:[3, 7, 9]レベル3:[12, 8, 6, 2]レベル0とレベル2のノード値は両方とも奇数なので厳密に増加しており、レベル 1 と 3 のノード値はすべて偶数で厳密に減少しているため、これは奇数偶数ツリーです。
例2:
入力: root = [5, 4, 2, 3, 3, 7]
出力: false
説明: 各層のノード値は、
0 層: [5]
1 層: [4, 2]
2 Layer :[3, 3, 7]
レベル 2 のノード値は厳密な増加条件を満たしていないため、これはパリティ ツリーではありません。
例 3:
入力: root = [5, 9, 1, 3, 5, 7]
出力: false
説明: レイヤ 1 のノード値は偶数である必要があります。
例 4:
入力: root = [1]
出力: true
例 5:
入力: root = [11, 8, 6, 1, 3, 9, 11, 30, 20, 18, 16, 12, 10, 4, 2, 17] 出力:
true
ヒント:
ツリー内のノード数の範囲は [1, 10^5]
1 <= Node.val <= 10^6です。
アイデア: 循環キューを使用して実装します。これは、レイヤ順のトラバース判定、レイヤごとの判定に相当します。アイデアは次のとおりです。
bool isEvenOddTree(struct TreeNode* root)
{
// 先开辟足够空间
struct TreeNode* queue[100002];
// front 为队头,出数据从队头出,减减 front 即可
// rear 为队尾,进数据从队尾进,加加 rear 即可
// prev 记录前驱节点
int front = 0, rear = 0, prev;
// 记录该层是奇还是偶;奇为1 ,偶为0
int EvenOdd = 0;
// 开始先进 root 节点
queue[rear++] = root;
// front 不等于 rear,说明队列不为空,继续进入循环
while (front != rear)
{
// cnt 为当前队列的有效节点个数
int cnt = rear - front;
// 如果是奇树,定义 prev 为整型的最大值,方便判断每一层上的节点严格递增
if (EvenOdd)
prev = INT_MAX;
// 偶数则定义 prev 为整型的最小值,方便判断每一层上的节点严格递减
else
prev = INT_MIN;
// 在有效节点个数的范围内循环
for (int i = 0; i < cnt; i++)
{
// 出队头的节点
root = queue[front++];
// 判断是奇树还是偶树,按照对应的树做对应的判断,不满足则返回 false
if ((EvenOdd == 0) && (root->val % 2 == 0 || prev >= root->val))
return false;
if ((EvenOdd == 1) && (root->val % 2 != 0 || prev <= root->val))
return false;
prev = root->val;
// 每出一个数据,判断如果 root 的左子树或右子树不为空,那就进队列
if (root->left)
queue[rear++] = root->left;
if (root->right)
queue[rear++] = root->right;
}
// 控制奇树层和偶树层
EvenOdd = (EvenOdd + 1) % 2;
}
return true;
}
Leetcode -1122. 配列の相対ソート
質問: arr1 と arr2 という 2 つの配列が与えられています。arr2 の要素は異なります。arr2 の各要素は arr1 に表示されます。
arr1 内の項目の相対的な順序が arr2 内の項目の相対的な順序と同じになるように、arr1 内の要素を並べ替えます。arr2 に現れない要素は、arr1 の最後に昇順で配置する必要があります。
例 1:
入力: arr1 = [2, 3, 1, 3, 2, 4, 6, 7, 9, 2, 19]、arr2 = [2, 1, 4, 3, 9, 6] 出力: [
2 、2、2、1、4、3、3、9、6、7、19]
例 2:
入力: arr1 = [28, 6, 22, 8, 44, 17]、arr2 = [22, 28, 8, 6]
出力: [22, 28, 8, 6, 17, 44]
ヒント:
1 <= arr1.length、arr2.length <= 1000
0 <= arr1[i]、arr2[i] <= 1000
arr2 の要素 arr2[i] は異なります
各要素 arr2[i in arr2 ] はすべて表示されますarr1 内
アイデア: ハッシュ配列を使用して、arr1 に出現する要素の回数を記録し、arr2 に出現する要素から arr1 に出現する回数を判断し、出現回数が一定になるまで arr1 の元の要素を上書きします。 0 に減らされる; 最終的に判断される arr2 に現れない arr1 の要素は後ろに直接追加できます; コードは次のとおりです:
int* relativeSortArray(int* arr1, int arr1Size, int* arr2, int arr2Size, int* returnSize)
{
// hash数组记录 arr1 数组中出现的元素的次数
// pos 记录覆盖当前 arr1 数组的长度
int hash[1001] = { 0 };
int pos = 0;
// 记录 arr1 数组中出现的元素的次数
for (int i = 0; i < arr1Size; i++)
{
hash[arr1[i]]++;
}
// 遍历 arr2 数组,arr2 中的元素如果在 arr1 中出现,就将 arr2 的元素覆盖在 arr1 中
// 然后出现的次数减减,一直覆盖直到在 hash 数组中出现的次数为0
for (int i = 0; i < arr2Size; i++)
{
while (hash[arr2[i]] != 0)
{
arr1[pos++] = arr2[i];
hash[arr2[i]]--;
}
}
// 判断 arr1 中没在 arr2 中出现的元素
// 直接在 arr1 后面补上
for (int i = 0; i < 1001; i++)
{
while (hash[i] != 0)
{
arr1[pos++] = i;
hash[i]--;
}
}
// 最后返回 arr1
*returnSize = arr1Size;
return arr1;
}