目次
この記事は、Datawhaleチームの調査計画の21番目のLeetCodeが選択したトピックグループTask09調査ノートです。
初心者の方は少し時間がかかり、多くの解決策は詳細に分析されておらず、将来改訂される可能性があります。ご容赦ください。
Datawhale学習ドキュメント:
https : //github.com/datawhalechina/team-learning-program/tree/master/LeetCodeTencent
0882つの順序付けられた配列をマージします
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/merge-sorted-array
2つの順序付き整数配列nums1とnums2を指定します。nums2をnums1にマージして、nums1を順序付き配列にしてください。
nums1とnums2の要素数をそれぞれmとnに初期化します。nums1のスペースサイズはm + nに等しいと想定できるため、nums2の要素を格納するのに十分なスペースがあります。
例:
入力:nums1 = [1,2,3,0,0,0]、m = 3、nums2 = [2,5,6]、n = 3
出力:[1,2,2,3,5,6]
入力:nums1 = [1]、m = 1、nums2 = []、n = 0
出力:[1]
アイデア
参照してください公式解決するために(コメント領域における最初の切手でのジョークHHH)
、順序を確認後、二分法、ダブルポインタ方式を検討し、不確実性に大きさを比較してみてください。タイトル要件がnums1にマージされていることに注意してください。
ポインタはnums1配列とnums2配列の先頭に配置され、最小値が比較されて出力配列に配置されます。
公式ソリューション図:
最適化:配列を最初から変更する場合、後続のデータへの影響を回避するために、nums1のデータを事前に保存する必要があります(これは新しい配列を作成することと同じです)。スペースを節約するために、最後から直接変更してください。
Pythonの実装
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
p1 = m - 1 # p1,p2分别指向两个数组的末尾
p2 = n - 1
p = m + n - 1 # 从末尾开始从小到大填入元素
while p1 >= 0 and p2 >= 0:
if nums1[p1] < nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p -= 1
nums1[:p2 + 1] = nums2[:p2 + 1] # 合并
089グレイコード
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/gray-code
グレイコーディングは、2つの連続する値が1桁だけ異なる2進数システムです。
コードの合計桁数を表す負でない整数nが与えられた場合、そのグレイコードシーケンスを出力します。複数の異なる回答がある場合でも、そのうちの1つを返すだけで済みます。
グレイコードシーケンスは0で始まる必要があります。
例:
入力:2
出力:[0,1,3,2]
入力:0
出力:[0]
説明:
00から0
01から1。
11から3。
10から2
所与N、グレーコード配列のために一意ではありません。
たとえば、[0,2,3,1]も有効なグレイコードシーケンスです。
00から0
10から2
11 - 3
01から1
さらに、グレイコードシーケンスは0で始まる必要があることを定義します。
合計桁数がnのグレイコードシーケンスが与えられた場合、その長さは2nです。n = 0の場合、長さは20 = 1です。
したがって、n = 0の場合、そのグレイコードシーケンスは[0]です。
アイデア
-
グレイコードは一意ではなく、1つのタイプのみを返す必要があります。このトピックには、数値変更の法則(一度に1ビットのみ)とバイナリ変換が含まれます。
参照問題の解決策https://leetcode-cn.com/problems/gray-code/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–12/、動的計画の方法は非常に賢いです。 -
派生を使用します。毎回1ビットしか変化せず、バイナリシステムの左から最初に見つかった「1」が「0」に変更されます。
参照:https:
//cloud.tencent.com/developer/article/1407014 -
バイナリ式の変換式-グレイコードもソリューションに含まれており、コードを直接記述することもできます。
Pythonの実装
(コードはもっと面倒ですが、個人的には理解しやすいと思います。ビット演算子の知識については、記事の最後を参照してください)
class Solution:
def grayCode(self, n: int) -> List[int]:
res = []
size = 1 << n # 位运算符,二进制下,从右侧推入零来推动最左边的位。
for i in range(size):
res.append((i >> 1) ^ i)
return res
104二分木の最大深さ
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/maximum-depth-of-binary-tree
二分木が与えられたら、その最大の深さを見つけます。
二分木の深さは、ルートノードから最も遠いリーフノードまでの最長パス上のノードの数です。
説明:リーフノードは、子ノードのないノードを指します。
例:
与えられた二分木[3,9,20、null、null、15,7]、
3
/ \
9 20
/ \
15 7
最大深度3を返します。
アイデア
公式の問題解決には、再帰と幅優先探索の2つの方法があります(実際には、深さ優先などがあります)。
Pythonの実装
再帰は比較的単純です(バイナリツリーの定義はコードの先頭にあります)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if root is None:
return 0
else:
left_height = self.maxDepth(root.left)
right_height = self.maxDepth(root.right)
return max(left_height, right_height) + 1
補足知識
ビット演算子
https://www.runoob.com/python/python-operators.html
https://www.w3school.com.cn/python/python_operators.asp
<<
左シフト演算子:オペランドのすべてのバイナリビットがにシフトされます左数桁、<<の右側の数字は移動する桁数を指定し、上位桁は破棄され、下位桁は0で埋められます。
たとえば、a = 60、バイナリ0011 1100
a << 2出力結果240、バイナリ解釈:1111 0000
<< =
代入演算子、x << = 3、つまりx = x << 3
これらの2つの演算子を使用すると、バイナリ計算をより便利に実行できます。たとえば、この記事のコードでは、size = 1 << n、n = 4の場合、1から10000まで4ビット左にシフトします。これは16です(上位ビットは破棄され、下位ビットは次のように入力されます)。 0)