LeetCodeノート:隔週コンテスト45コンテスト記録

0.試合後のまとめ

今回は全体的に大丈夫です。4つの質問がすべて終わったので総合ランキングはかなり高いですが、最後の質問のやり方が違うので、実は運の要素があることがわかりました。最善の解決策ですが、それは満たされています。タイムアウトの問題に関しては、ゲーム中にたまたま通過したのは運だけです...

要するに、道はまだ長いので、ゆっくりと給油しなければなりません...

1.トピック1

質問1に与えられた質問へのリンクは次のとおりです。

1.問題解決のアイデア

最初の質問については何も言うことはありません。カウンターを使用して各要素の出現回数を記録し、1回だけ出現した要素を合計します。

2.コードの実装

Pythonコードは次のとおりです。

class Solution:
    def sumOfUnique(self, nums: List[int]) -> int:
        cnt = Counter(nums)
        eff = [x for x in cnt if cnt[x] == 1]
        return sum(eff) if eff != [] else 0

評価のためにコードを送信した後、44ミリ秒かかり、14.5MBのメモリを消費しました。

2.トピック2

トピック2のテスト問題へのリンクは次のとおりです。

1.問題解決のアイデア

この質問の本質は、最大の部分文字列と最小の部分文字列を見つけ、絶対値をとって2つの最大値を見つけることです。

最大の部分文字列または最小の部分文字列を取得する方法については、累積合計を見つけてから、単調に増加/減少する部分文字列を見つけることができます。

2.コードの実装

Pythonコードは次のとおりです。

class Solution:
    def maxAbsoluteSum(self, nums: List[int]) -> int:
        s = [0] + list(accumulate(nums))
        n = len(s)
        l2r = [0]
        r2l = [0]
        res = 0
        for i in range(1, n):
            while l2r != [] and  l2r[-1] >= s[i]:
                l2r.pop()
            l2r.append(s[i])
            res = max(res, l2r[-1]-l2r[0])
            
            while r2l != [] and  r2l[-1] <= s[i]:
                r2l.pop()
            r2l.append(s[i])
            res = max(res, r2l[0] - r2l[-1])
        return res

評価のためにコードを送信した後、756ミリ秒かかり、28.7MBのメモリを消費しました。

3.トピック3

トピック3のテスト問題へのリンクは次のとおりです。

1.問題解決のアイデア

この質問のアイデアは、元の文字列が同じ連続文字に従って連続的にクラスター化され、タイトルに従って前後の同じ文字が削除される限り、前の質問よりも簡単に感じます。

注意すべき唯一のことは、文字列が1つのタイプの文字のみに削除された場合、文字が1つしかない場合は、1を返し、それ以外の場合は0を返すことです。

2.コードの実装

Pythonコードは次のとおりです。

class Solution:
    def minimumLength(self, s: str) -> int:
        record = []
        n = len(s)
        cnt = 1
        for i in range(1, n):
            if s[i] == s[i-1]:
                cnt += 1
            else:
                record.append((s[i-1], cnt))
                cnt = 1
        record.append((s[n-1], cnt))
        while len(record) > 1 and record[0][0] == record[-1][0]:
            record.pop(0)
            record.pop(-1)
        if len(record) == 1:
            return 0 if record[0][1] > 1 else record[0][1]
        
        return sum([x[1] for x in record])

評価のためにコードを送信した後、584ミリ秒かかり、22.2MBのメモリを消費しました。

4.トピック4

質問4のテスト問題へのリンクは次のとおりです。

1.問題解決のアイデア

競技中、深さ優先探索法を使ってこの問題を実行しました。当時は幸運にも一度合格できましたが、8秒以上かかりました。翌日再提出したところ合格できませんでした。それ...

次に、他の人の解決策を調べたところ、全体的な時間が約1秒であり、アルゴリズムはすべて動的計画法を使用していることがわかりました。動的計画法を使用してこの問題のアルゴリズムを実装する方法をよく見てみましょう。


現在のオンラインの回答を見ると、主なアイデアは次のとおりです。

  • 動的計画法項目dp(idx, k)は、idxth会議から取得でき、最大k個の会議に参加できる最大会議値として定義されます。

この時点で、すぐに次のように漸化式を取得できるようになります。

dp(idx, k) = max(events[idx][2] + dp(nxt, k-1), dp(idx+1, k))

その中で、前者は会議に参加している状況を指し、後者は会議に参加していない状況を指します。

これから、コードの実装をすばやく行うことができます。

2.コードの実装

Pythonコードは次のとおりです。


import bisect

class Solution:
    def maxValue(self, events: List[List[int]], k: int) -> int:
        events = sorted(events)
        st_list = [x[0] for x in events]
        n = len(events)
        
        @lru_cache(None)
        def dp(idx, k):
            if idx == n:
                return 0
            if k == 0:
                return 0
            ed = events[idx][1]
            nxt = bisect.bisect_left(st_list, ed+1)
            return max(events[idx][2]+dp(nxt, k-1), dp(idx+1, k))
        
        return dp(0, k)

評価のためにコードを送信した後、876ミリ秒かかり、217.1MBのメモリを占有しました。

おすすめ

転載: blog.csdn.net/codename_cys/article/details/113781802