สมมติว่าเรามีสตริง เราสามารถสร้างลำดับของสตริงนั้นได้โดยการลบอักขระบางตัว (อาจไม่มีการลบ) ดังนั้นหากมีสตริงต้นทางและเป้าหมายสองสตริง เราต้องหาจำนวนลำดับย่อยของซอร์สขั้นต่ำเพื่อให้การเรียงต่อกันเท่ากับเป้าหมาย หากงานนั้นเป็นไปไม่ได้ ให้คืนค่า -1 ดังนั้นหากแหล่งที่มาคือ "abc" และเป้าหมายคือ "abcbc" ผลลัพธ์จะเป็น 2
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดสตริงที่เรียกว่า เป็นไปได้ ซึ่งจะใช้ s และ t เป็นอินพุต
-
สร้างแผนที่ ม
-
สำหรับแต่ละอักขระ c ใน s เครื่องหมาย m[c] :=1
-
สำหรับแต่ละอักขระ c ใน t ถ้า m[c] เป็น 0 ให้คืนค่าเท็จ
-
คืนความจริง
-
จากวิธีหลัก ให้ทำดังต่อไปนี้ −
-
ssz :=ขนาดของ s และ tsz :=ขนาดของ t
-
สร้างแผนที่ m ของคีย์ประเภทอักขระและค่าประเภทอาร์เรย์
-
สำหรับฉันอยู่ในช่วง 0 ถึง ssz
-
แทรก i ลงใน m[s[i]]
-
-
ก่อน :=-1 และ ret :=1
-
สำหรับฉันอยู่ในช่วง 0 ถึง tsz
-
ถ้า t[i] ไม่มีอยู่ใน m ให้คืนค่า -1
-
v :=m[t[i]]
-
set i :=ดัชนีขององค์ประกอบใน v ที่มากกว่า pre
-
ถ้าฉันไม่ใช่จุดสิ้นสุดของรายการ
-
เพิ่ม ret โดย 1 และก่อน :=v[0]
-
-
อย่างอื่นก่อน :=v[i]
-
-
รีเทิร์น
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool possible(string s, string t){
map <char, int> m;
for(int i = 0; i < s.size(); i++){
m[s[i]] = 1;
}
for(int i = 0; i < t.size(); i++){
if(!m[t[i]])return false;
}
return true;
}
int shortestWay(string s, string t) {
int ssz = s.size();
int tsz = t.size();
map <char, vector <int> > m;
for(int i = 0; i < ssz; i++){
m[s[i]].push_back(i);
}
int pre = -1;
int ret = 1;
for(int i = 0; i < tsz; i++){
if(!m.count(t[i]))return -1;
vector <int>& v = m[t[i]];
vector <int> :: iterator it = upper_bound(v.begin(),
v.end(), pre);
if(it == v.end()){
ret++;
pre = v[0];
}else{
pre = *it;
}
}
return ret;
}
};
main(){
Solution ob;
cout << (ob.shortestWay("abc", "abcbc"));
} อินพุต
"abc" "abcbc"
ผลลัพธ์
2