本週心得
- vector中,字符串的sort()排序問題(按順序以字母表比較,前一位優先級高:abc < acb < bca)
- 數組中的排序sort問題:(sort函數作用範圍爲 [begin, end) ,不包含最後一位 )
靜態數組:int a[10] = { 9, 0, 1, 2, 3, 7, 4, 5, 8, 6 }; sort(a, a +10);
(注意加的是長度,加到數組末尾的下一位)
vector: sort(heights.begin(), heights.end());
(vector中的end()代表的是最後一位數的下一位)- string.substr(int start_index, int length)的用法:
兩個參數時,第一個是起始位置,第二個是子串長度 eg: substr(0,5)獲得字符串s中 從第0位開始的長度爲5的字符串
一個參數時默認從指定開始位置到尾 eg: substr(1) ) 獲得字符串s中 從第1位開始的到結尾的字符串- char字符串數組是以 ‘\0’ 爲結尾的,但是string 是一個類,結尾沒有字符’\0’
- C++刪除string最後一個字符的幾種方法:
- str.pop_back();
- str.erase(str.end() - 1);
- str = str.substr(0, str.length() - 1);- string.erase()的用法
(1)erase(pos,n); 刪除從pos開始的n個字符,比如erase(0,1)就是刪除第一個字符
(2)erase(first, last);刪除從first到 last之間的字符(first和last都是迭代器)
(3)erase(pos);刪除pos處的一個字符(pos必須是個string類型的迭代器 string::iterator pos)- 尋找質數的算法:厄拉多塞篩法(精簡高效尋找每個數字的倍數的算法)
- 關於字符的轉碼問題:
char to int : 一般使用 char - ‘0’
int to cha : 一般使用 int + ‘0’
(注意: char(4) : 將4轉變爲’\4’而不是 字符 ‘4’,int(‘a’): 將字符串轉換爲對應的ASCII碼
因此涉及int/char轉換問題最好使用 ±’0’,其中 (char) 絕對不要使用!)- 判斷vector中有無某值:(STL)find
vector<int>::iterator it = find(arr.begin(),arr.end(),res);
if( it != arr.end() ) //值在數組中
if( it == arr.end() ) //值不在數組中
- 弗洛伊德循環查找算法 (快慢指針法/龜兔指針法)
原理:兔子每走一步就向烏龜靠近一個節點(在它們的移動方向上)。若有則必相遇
用於判斷一個鏈表是否有循環
594,最長和諧子序列
class Solution {
public:
int findLHS(vector<int>& nums) {
unordered_map<int, int> hash;
for(auto num:nums)
hash[num]++;
int res = 0;
for(auto i : hash)
//if(hash[i.first+1] != 0)
if(hash.count(i.first+1))
res = max(res, i.second + hash[i.first + 1]);
return res;
}
};
1160, 拼寫單詞
class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
int res=0;
int ch[26]={0};
for(char c:chars)
ch[c-'a']++;
for(string word:words)
{
int wd[26]={0};
for(char c:word)
wd[c-'a']++;
res+=word.size();
for(char c:word)
{
if(ch[c-'a']<wd[c-'a'])
{
res-=word.size();
break;
}
}
}
return res;
}
};
572, 分糖果
class Solution {
public:
int distributeCandies(vector<int>& candies) {
int nums = candies.size();
vector<int> hash(10000);
for(int i = 0; i < nums; i++){
hash[candies[i]]++;
}
int res = 0;
for(int i = 0; i < 10000; i++){
if(hash[i] >= 2) res++;
else if(hash[i] == 1 && res < (nums/2) ) res++;
}
return min(nums/2, res);
}
};
599 兩個列表共同元素的最小索引總和
class Solution {
public:
vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) {
unordered_map<string, int> hash;
//unordered_map<string, unordered_map> hash;
int i = 0;
for(auto r1 : list1){
i++;
hash[r1] += i;
}
int j = 0;
for(auto r2 : list2){
j++;
if(hash[r2] != 0){
int tmp = -hash[r2];
hash[r2] = tmp;
hash[r2] -= j;
}
}
int min_res = INT_MAX;
for(auto h:hash){
if(h.second < 0)
min_res = min(min_res, -h.second);
}
vector<string> arr_res;
for(auto h:hash){
if(-h.second == min_res)
arr_res.push_back(h.first);
}
return arr_res;
}
};
1078. Bigram分詞
這題有很多小細節:
- char字符串數組是以 ‘\0’ 爲結尾的,但是string 是一個類,結尾沒有字符’\0’(string 是以字符串長度,來判斷結束的),故所以在這題的string里加了一個’\0’來作爲結束判斷符
- string 中的常用操作:
刪除:earse(Iterator,Iterator);
末尾添加字符 append(個數,char);
class Solution {
public:
vector<string> findOcurrences(string text, string first, string second) {
vector<string> str_arr;
string str;
text.append(1,'\0');
for(auto c : text){
if(c == ' ' || c == '\0'){
str_arr.push_back(str);
str.erase (str.begin(), str.end());
}
else
str.append(1, c);
}
vector<string> res;
for(int i = 1; i<str_arr.size(); i++){
if(str_arr[i - 1] == first && str_arr[i] == second && i != str_arr.size() - 1)
res.push_back(str_arr[i + 1]);
}
return res;
}
};
645.錯誤的集合
注意:在這裏hash表的 初始化 和 指定操作 分開進行,達到目的
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
unordered_map<int, int> hash;
for(int i = 0; i < nums.size();i++){
hash[i] = 0;
}
for(auto num:nums){
hash[num-1]++;
}
vector<int> res;
for(auto h:hash){
if(h.second == 2)
res.push_back(h.first+1);
}
for(auto h:hash){
if(h.second == 0)
res.push_back(h.first+1);
}
return res;
}
};
720,詞典中最長的單詞
const int MAX_NODE = 1000000 + 10;
const int CHARSET = 26;
int trie[MAX_NODE][CHARSET] = {0};
int ending[MAX_NODE] = {0};
int k = 1; // k爲節點標記
void insert(string w){ //在Trie樹中插入一個單詞
int len = w.size();
int p = 0; // p爲動態節點標記
for(int i=0; i<len; i++){
int c = w[i] - 'a';
if(!trie[p][c]){
trie[p][c] = k;
k++;
}
p = trie[p][c];
}
ending[p] = 1; //ending數組是個hash表,記錄爲終止節點的節點標記k
}
int search(string s){
int len = s.size();
int p = 0;
for(int i=0; i<len; i++){
int c = s[i] - 'a';
if(!trie[p][c]) return 0;
p = trie[p][c];
}
return ending[p] == 1;
}
class Solution {
public:
string longestWord(vector<string>& words) {
for(auto word:words){
insert(word);
}
vector<string> res_arr;
for(auto word:words){
int length = word.size();
bool flag = 1;
while(length){
if(!search(word.substr(0,length--))){
flag = 0;
break;
}
}
if(flag)
res_arr.push_back(word);
}
int max_len = 0;
for(auto s:res_arr){
int s_len = s.size();
max_len = max(max_len, s_len);
}
vector<string> res;
for(auto s:res_arr){
if(s.size() == max_len)
res.push_back(s);
}
sort(res.begin(), res.end());
return res[0];
}
};
204 尋找質數
厄拉多塞篩法: 高效for循環創建hash表
class Solution {
public:
int countPrimes(int n) {
int count = 0;
//初始默認所有數爲質數
vector<bool> signs(n, true);
for (int i = 2; i < n; i++) {
if (signs[i]) {
count++;
for (int j = i + i; j < n; j += i) {
//排除不是質數的數
signs[j] = false;
}
}
}
return count;
}
};
202 快樂數
快樂數:各個位數平方和爲1,非1和可繼續循環,最終爲1即可)
tips:爲了防止無限循環,可以用數組記憶已出現的值,再次出現說明死循環
class Solution {
public:
bool isHappy(int n) {
unordered_map<char, int> hash;
for(int i =0; i<10;i++){
hash[i+'0'] = i*i; //hash[char(i)] 錯誤 ---(char)將4轉變爲'\4'而不是'4';
}
int tacket = n;
vector<int> arr;
while(1){
string num = to_string(tacket);
int res = 0;
for(auto c:num){
res += hash[c];
}
if(res == 1) return 1;
vector<int>::iterator it=find(arr.begin(),arr.end(),res);
if(it != arr.end()) return 0;
else arr.push_back(res);
tacket = res;
}
return 0;
}
};