算法:字符串数组问题
主要工具:hash table
在长度为n的母串中匹配长度为m的子串
Brute-force算法:(暴力求解)顺序遍历母串,将每个字符作为匹配字符,判断是否匹配子串。时间复杂度O(m*n)
char * Strstr(const char *str, const char * target)
{
if (! *target)
return str;
char *p1 = (char*)str;
while(*p1)
{
char *p1Begin = p1;
*p2 = (char*) target;
while(*p1 && *p2 && *p1==*p2)
{
p1++;
p2++;
}
if ( !*p2 )
return p1Begin;
p1 = p1Begin+1;
}
return NULL;
}
Rabin-Karp算法:
确定字符串中的字符是否唯一
hashmap:
bool is unique(string input)
{
bitset<256> hashMap;
for(int i=0; i<input.length; i++)
{
if(hashmap[(int)input[i]])
{
return false;
}
hashMap[int)input[i]] = 1;
}
return true;
}
给定两个字符串确定它们是否是彼此的置换:
bool isPermutation(string stringA, string stringB)
{
if (stringA.length() != stringB.length())
{
return false;
}
unordered_map<char, int> hashMapA;
unordered_map<char,int> hashMapB;
for(int i = 0; i < stringA.length(); i++)
{
hashMapA[stringA[i]]++;
hashMapB[stringB[i]]++;
}
if(hashMapA.size() != hashMapB.size())
{
return false;
}
unordered_map<char, int>::iterator it;
for(it = hashMapA.begin(); it != hashMapA.end(); it++)
{
if(it->second != hashMapB[it->first])
{
return false;
}
}
return ture;
}
将newspaper和message作为两个字符串,检查消息是否可以用报纸中的字母组成
message中任意字符出现次数要小于其在newspaper中出现的次数
bool isCompose(string newspaper, string message)
{
unordered_map<chat, int> hashMap;
int i;
if(newspaper.length() < message.length())
{
return false;
}
for(int i = 0; i < newspaper.length(); i++)
{
hashMap[newspaper[i]]++;
}
for (i = 0; i < message.length; i++)
{
if(hash.count(message[i]) == 0)
return false;
if(--hashMap[message[i]] < 0)
return false;
}
}
return true;
在一个数组中查找是否有其中两个数字相加的和为目标数
vector<int> addsToTarget(vector<int> &numbers, int target)
{
unordered_map<int, int> numToindex;//哈希表
vector<int> vi(2);//保存符合条件的两个数
for( auto it = numbers.begin; it != numbers.end(); it++)
{
if(numToindex.count(target-*it))//当找到第二个数时便进入
{
vi[0] = numToindex[target - *it] + 1;
vi[1] = (int)(it - numbers.begin()) + 1;
return vi;//返回值为vector
}
numToindex[*it] = (int)(it - numbers.begin());//相当于保存第一个数的下标
}
}
获取数组中最长连续元素序列的长度
用hash表存储元素的上一位和下一位,更新最小值和最大值就能唯一确定序列
struct bound
{
int high;
int low;
bound(int h = 0, int l = 0)
{
high = h;
low = l;
}
};
int longestConsecutive(vector<int> &num)
{
unordered_map<int, bound> table;
int local;
int maxLen = 0;
for (int i = 0; i < num.size(); i++)
{
if (table.count(num[i]))//将每一个元素都放入hash表中,并跳过重复元素
continue;
local = num[i];
int low = local;
int high = local;
if (table.count(local - 1))//查找当前元素-1是否在哈希表中
{
low = table[local - 1].low;更新最小值
}
if (table.count(local + 1))//查找当前元素+1是否在哈希表中
{
high = table[local + 1].high;//更新最大值
}
//对于没有连续序列的单个元素,low与high都等于自身
//对于连续序列,low和high将更新为当前最小值和最大值
table[low].high = table[local].high = high;
table[high].low = table[local].low = low;
if (high - low + 1 > maxLen)
{
maxLen = high - low + 1;
}
}
return maxLen;
}
查找最长公共子串
注意防止访问越界
int LongestCommonSubstring(string &A, string &B)
{
if (A.empty() || B.empty())
{
return 0;
}
int lcs = 0, lcs_temp = 0;
for (int i = 0; i < A.size(); ++i)
{
for (int j = 0; j < B.size(); ++j)
lcs_temp = 0;
{
while ((i + lcs_temp < A.size()) && (j + lcs_temp < B.size()) && (A[i + lcs_temp] == B[j + lcs_temp]))
{
++lcs_temp;
}
if (lcs_temp>lcs)
{
lcs = lcs_temp;
}
}
}
return lcs;
}