單週賽 253 題解
阿新 • • 發佈:2021-08-16
知識點:字串比較,大根堆,貪心,最長上升子序列,二分優化
,返回操作後 \(a\) 的陣列和的可能的最小值
知識點:字串比較,大根堆,貪心,最長上升子序列,二分優化
檢查字串是否為陣列字首
給定一個字串 \(s\),給定一個字典 \(w\),如果 \(w\) 中前 \(k\) 個字串可以構成 \(s\),返回 \(true\),否則返回 \(false\),其中 \(1\leq k\leq w.size\)
題解
模擬
// cpp class Solution { public: bool isPrefixString(string s, vector<string>& words) { string temp; for (int i = 0; i < words.size(); ++i) { temp += words[i]; if (s == temp) return 1; } return 0; } };
// go
func isPrefixString(s string, w []string) bool {
var temp string
for _, i := range w {
temp += i
if s == temp {
return true
}
}
return false
}
移除石子使總數最小
給定長 \(n\) 的陣列 \(a\),給定 \(k\),執行 \(k\) 次操作,每次把 \(a_{i}\) 減去 \(\lfloor\frac{a_{i}}{2}\rfloor\)
題解
貪心,每次對最大的 \(a_{i}\) 操作即可,使用優先佇列維護,時間複雜度 \(O(n\log n)\)
// cpp class Solution { public: int minStoneSum(vector<int>& piles, int k) { priority_queue<int> pq; for (auto &i: piles) pq.push(i); while (k--) { int top = pq.top(); pq.pop(); pq.push(top - top / 2); } int ans = 0; while (!pq.empty()) { ans += pq.top(); pq.pop(); } return ans; } };
使字串平衡的最小交換次數
給定 [
和 ]
組成的字串,你可以交換任意兩個括號,使得整體括號匹配,返回最小的交換數
保證左右括號數相等
題解
找規律,對於題設中的字串,一定可以抽象成 ]]]]][[[[[
的形式,設共有 \(n\) 對,那麼答案即為 \(\lceil\frac{n}{2}\rceil\)
// cpp
class Solution {
public:
int minSwaps(string s) {
int l = 0, r = 0;
for (auto &i: s) {
if (i == '[') l++;
else {
if (l) l--;
else r++;
}
}
return (r + 1) / 2;
}
};
// go
func minSwaps(s string) int {
l := 0
r := 0
for _, i := range(s) {
if i == '[' {
l++
} else {
if l > 0 {
l--
} else {
r++
}
}
}
return (r + 1) / 2
}
找出到每個位置為止最長的有效障礙賽跑路線
給定長為 \(n\) 的陣列 \(a\),找到以每個位置 \(i\) 結尾的最長不降子序列的長度,以陣列形式返回
資料規定
\(1\leq n\leq 10^5\)
題解
使用 \(LIS\) 的二分解法
具體來講,設 \(dp[i]\) 表示長為 \(i + 1\) 的最長不降子序列的最後一個位置的最小值,初始化為 \(inf\)
對於每一個位置 \(i\),可以在 \(dp\) 陣列中二分查詢最後一個小於 \(a[i]\) 的位置,並把 \(a[i]\) 賦值在該位置後面,獲取最長不降子序列的長度只需要用該位置減去陣列頭,維護答案即可
舉個例子,對 a[4] = [1, 2, 3, 2]
進行操作
dp 陣列初始化:
[inf, inf, inf, inf]
處理 a[0] = 1,得到:
[1, inf, inf, inf]
處理 a[1] = 2,得到:
[1, 2, inf, inf]
處理 a[2] = 3,得到:
[1, 2, 3, inf]
處理 a[3] = 2,得到:
[1, 2, 2, inf]
// cpp
class Solution {
public:
#define inf 0x3f3f3f3f
vector<int> longestObstacleCourseAtEachPosition(vector<int>& o) {
int n = o.size();
vector<int> dp(n + 7), ans(n + 7);
fill(dp.begin(), dp.end(), inf);
for (int i = 0; i < n; ++i) {
int len = upper_bound(dp.begin(), dp.end(), o[i]) - dp.begin() + 1;
*upper_bound(dp.begin(), dp.end(), o[i]) = o[i];
ans[i] = len;
}
return {ans.begin(), ans.begin() + n};
}
};