Re: [閒聊] 每日leetcode已回收

看板Marginalman作者 (是oin捏)時間1年前 (2024/04/30 15:59), 編輯推噓4(4017)
留言21則, 6人參與, 1年前最新討論串172/1548 (看更多)
※ 引述 《Rushia (早瀬ユウカの体操服)》 之銘言: :   : https://leetcode.com/problems/number-of-wonderful-substrings/description : 1915. Number of Wonderful Substrings : 給你一個包含小寫字母a~j的字串,如果一個子字串的所有字母只有一個字母出現奇數次 : 那麼他就是一個超讚字串,求出s裏面有幾個超讚子字串。 :   : 思路: : 1.我們要判斷一個字串是不是超讚字串要檢查他的奇偶,我們可以用一個二進位數字表 : 示,奇數為1偶數為0,因為有10個 字母所以需要10位數的二進制就可以表示,狀 : 態初始化為0000000000 -> i = -1 (什麼都不加必定是偶數) : 假設加入一個a狀態變成1000000000 -> i = 0 : 加入一個b狀態變成1100000000 -> i = 1 : 加入一個a狀態變成0100000000 -> i = 2 : 加入一個b狀態變成0000000000 -> i = 3 : ... : 為了方便討論,後面我們稱二進位數字為"狀態" :   : 2.如果 i 不同但是狀態相同(例如上面i=-1和i=3),兩個"狀態"之間的字母必定只會出 : 現偶數次(奇數不可能相同),所以: : b ... [xxxxx] ... b :   : 如果最後一個b的狀態等於前面的那個b,可以不斷地擴展會變成: :   : b -> [中間必定是偶數] -> b -> [中間必定是偶數] -> b :   : 因為這個特性,只要當前的狀態前面出現過,他就可以跟前面的狀態接在一起變成一 : 個新的超讚數字,就像是 : b => bb => bbb : 這樣所以我們只要找有幾個b就好,找的過程又可以分成奇偶兩個case。 :   : 3.可以使用前綴和技巧求解,因為最多有2^10個狀態所以可以把map換成array : 假定 cnt[x] 表示二進位x這個狀態的出現次數: : (1) 任何數加上偶數,奇偶性不變。 : 同第二點所述,累加前面的 cnt[x] 總數(只要該狀態有出現過就一定可以累加) : (2) 任何數加上奇數,奇數變偶數,偶數變奇數。 : 假設前面存在一個前綴字串 x 可和 word[i] 組成一個超讚字串,那麼必定滿足: : x ^ word[i] = 只有一個一的二進位數 : 而該數x剛好會等於 word[i] 的狀態每個位數翻轉1,假定 word[i]=0000000010 : 0000000011 ^ 0000000010 = 0000000001 : 0000000000 ^ 0000000010 = 0000000010 : 0000000110 ^ 0000000010 = 0000000100 : 0000001010 ^ 0000000010 = 0000001000 : 0000010010 ^ 0000000010 = 0000010000 : 0000100010 ^ 0000000010 = 0000100000 : 0001000010 ^ 0000000010 = 0001000000 : 0010000010 ^ 0000000010 = 0010000000 : 0100000010 ^ 0000000010 = 0100000000 : 1000000010 ^ 0000000010 = 1000000000 : 所以我們去找前面所有 word[i] 翻轉一個位元的狀態共有幾個,全部累加起來就好。 思路: 哇靠 這三小 這是dp嗎? (30分鐘之後) 幹拎娘 誰他媽給這標成medium 的 摧毀別人自尊很好玩是不是 怎麼不去給狗幹 對不起對不起對不起對不起對不起對不起 然後我跑去留言區看提示 bitset prefix sum 好 我試試看 結果成功 好爽 https://i.imgur.com/oBstnsI.jpeg
先把他弄成只有四個字母的bitset試試看 為什麼只有0跟1? 因為有幾個根本不重要 重點是他字串開頭到結尾有幾個奇數的 開始進入word 然後先看第一個字 改變當時bitset 並且記錄 同時去前面看有沒有能接的bitset 然後再繼續幹到最後 怎麼看有沒有能接的bitset? 他進來的時候 如果要只有一個以下是奇數 那這樣 代表 1: 他就都沒有 2: 他有一個 然後往回找要找什麼? 1: 要找的是最多一個奇數的 2: 要找的就是可以跟他弄成剛好沒有奇數的 所以往回找時 要看兩個情況 1: 剛好跟他差一個bit的 也就是說他們之間剛好多一個或是少一個奇數 2: 找到跟他bitset長一樣 就是一樣的 這樣他們兩個之間就一定是都是偶數 然後1跟2都可以直接加上 在那個位子出現的子字串 也就是那一種bitset的數量 ```cpp class Solution { public: long long wonderfulSubstrings(string word) { long long res = 0; int len = word.size(); bitset<10> now; bitset<10> nowone; unordered_map<bitset<10>,long long> paper; paper[now]++; for(int i = 0 ; i < len ; i ++) { now[word[i]-'a'] = now[word[i]-'a'] ^ 1; for(int j = 0 ; j < 10 ; j ++) { nowone = now; nowone[j] = nowone[j] ^ 1; res += paper[nowone]; } res += paper[now]; paper[now] ++; } return res; } }; ``` -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.162.62.124 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1714463998.A.D87.html

04/30 16:00, 1年前 , 1F
你可以上咕咕嚕了 你比我還強
04/30 16:00, 1F

04/30 16:01, 1年前 , 2F
我看提示運氣好想對方向 球球四大碩士廷廷不要尻洗我
04/30 16:01, 2F

04/30 16:01, 1年前 , 3F
你什麼時候去姑姑魯 我有過前幾筆測資
04/30 16:01, 3F

04/30 16:01, 1年前 , 4F
但最後還是看解答 有夠難
04/30 16:01, 4F

04/30 16:03, 1年前 , 5F
我前30分鐘都在想10*10^5那種從雜湊裡面找index的slid
04/30 16:03, 5F

04/30 16:03, 1年前 , 6F
ing window 然後想不出來 我流淚了
04/30 16:03, 6F

04/30 16:04, 1年前 , 7F
你板剩我姐不出來了
04/30 16:04, 7F

04/30 16:04, 1年前 , 8F
每次要找那個左右移動的index都要再看一次中間有多少
04/30 16:04, 8F

04/30 16:04, 1年前 , 9F
奇數偶數 最後根本就是n^2
04/30 16:04, 9F

04/30 16:05, 1年前 , 10F
你好棒
04/30 16:05, 10F

04/30 16:05, 1年前 , 11F
程式設計婊子
04/30 16:05, 11F

04/30 16:06, 1年前 , 12F
謝謝 謝謝喔 我是婊子
04/30 16:06, 12F

04/30 16:08, 1年前 , 13F
我前半小時想到XOR 過前幾筆 然後多想半小時沒想法
04/30 16:08, 13F

04/30 16:08, 1年前 , 14F
看解答 然後WTF
04/30 16:08, 14F

04/30 16:10, 1年前 , 15F
是超時嗎 如果這題側資小一點 能用n^2 才有資格就medi
04/30 16:10, 15F

04/30 16:10, 1年前 , 16F
um 吧
04/30 16:10, 16F

04/30 16:10, 1年前 , 17F
這雜湊表+bitset+前綴和 還要隨時更新 幹你老師 誰寫
04/30 16:10, 17F

04/30 16:10, 1年前 , 18F
的出來
04/30 16:10, 18F

04/30 16:12, 1年前 , 19F
超時
04/30 16:12, 19F

04/30 16:13, 1年前 , 20F
寶 我們一起去北車乞討 O(n)的世界已經容不下我們了
04/30 16:13, 20F

04/30 16:28, 1年前 , 21F
大師
04/30 16:28, 21F
文章代碼(AID): #1cCAJ-s7 (Marginalman)
討論串 (同標題文章)
文章代碼(AID): #1cCAJ-s7 (Marginalman)