(i) 拉链法解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于 1,但一般均取α≤1.
#define SIZE 10 //哈希表大小为10
//定义哈希表数据结构
typedef struct hashNode
{
int data;
struct hashNode *next;
}hashNode;
struct hashNode HashLink[SIZE];
int m; //大小为全局变量
//初始化哈希表
void initHashTable()
{
int i;
m=SIZE;
for(i=0;idata=key;
while(hashFunc(key) != hashLink[i].data) //查找位置
i++;
//将p结点插入到位置i的哈希链表中,头插
p->next=hashLink[i].next;
hashLink[i].next=p;
return i;
}
//查找
int findHash(int key)
{
int addr=hashFunc(key);
int i=0;
hashNode *p; //p指向哈希表首地址
if(!hashLink[addr].next) //若开始哈希表无元素,直接返回
{
printf("元素%d不在哈希表中\n",key);
return 0;
}
p=hashLink[addr].next;
while(p!=NULL && (p->data!=key))
{
p=p->next;
i++;
}
if(p->data==key)
{
printf("元素%d不在哈希表中,地址为%d \n",key,addr);
return 0;
}
else
{
printf("元素%d不在哈希表中\n",key);
return 0;
}
return 0;
}
LRU是一种应用在操作系统上的缓存替换策略,和我们常见的FIFO算法一样,都是用于操作系统中内存管理中的页面替换,其全称叫做Least Recently Used(近期最少使用算法),算法主要是根据数据的历史访问记录来进行数据的淘汰,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
LeetCode 146
代码参考
#include
#include
#include
#include
using namespace std;
using namespace stdext;
class LRUCache{
public:
LRUCache(int capacity) {
m_capacity = capacity ;
}
int get(int key) {
int retValue = -1 ;
hash_map > :: iterator> ::iterator it = cachesMap.find(key) ;
//如果在Cashe中,将记录移动到链表的最前端
if (it != cachesMap.end())
{
retValue = it ->second->second ;
//移动到最前端
list > :: iterator ptrPair = it -> second ;
pair tmpPair = *ptrPair ;
caches.erase(ptrPair) ;
caches.push_front(tmpPair) ;
//修改map中的值
cachesMap[key] = caches.begin() ;
}
return retValue ;
}
void set(int key, int value) {
hash_map > :: iterator> ::iterator it = cachesMap.find(key) ;
if (it != cachesMap.end()) //已经存在其中
{
list > :: iterator ptrPait = it ->second ;
ptrPait->second = value ;
//移动到最前面
pair tmpPair = *ptrPait ;
caches.erase(ptrPait) ;
caches.push_front(tmpPair) ;
//更新map
cachesMap[key] = caches.begin() ;
}
else //不存在其中
{
pair tmpPair = make_pair(key, value) ;
if (m_capacity == caches.size()) //已经满
{
int delKey = caches.back().first ;
caches.pop_back() ; //删除最后一个
//删除在map中的相应项
hash_map > :: iterator> ::iterator delIt = cachesMap.find(delKey) ;
cachesMap.erase(delIt) ;
}
caches.push_front(tmpPair) ;
cachesMap[key] = caches.begin() ; //更新map
}
}
private:
int m_capacity ; //cashe的大小
list > caches ; //用一个双链表存储cashe的内容
hash_map< int, list > :: iterator> cachesMap ; //使用map加快查找的速度
};
LeetCode 1 两数之和
//哈希思想实现
class Solution {
public:
vector twoSum(vector& nums, int target) {
unordered_map map; //unordered_map关联容器
int n=(int) nums.size();
for(int i=0;isecond,i};
}
map[nums[i]]=i;
}
}
};
LeetCode 202 Happy Number
//哈希思想实现
class Solution {
public:
bool isHappy(int n) {
unordered_set v;
while(v.find(n)==v.end()){
v.insert(n);
int temp=0;
while(n){
tmp+=(n%10)*(n%10);
n/=10;
}
n=tmp;
if(n==1)
return true;
}
return false;
}
};
字典树(Trie树)
字典树,又称单词查找树,Trie树,是一种树形结构,典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度的减少无谓的字符串比较,查询效率比哈希表高。
//结点
class Node{
public:
Node* next[26];
int num;
Node(){
num=0;
for(int i=0;i<26;i++)
next[i] = NULL;
}
};
class Trie {
public:
Node* root;
/** Initialize your data structure here. */
Trie() {
root=new Node();
}
/** Inserts a word into the trie. */
void insert(string word) {
Node* p=root;
for(int i=0;inext[word[i]-'a']==NULL){
p->next[word[i]-'a']==new Node();
}
p=p->next[word[i]-'a'];
}
p->num++;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Node* p=root;
for(int i=0;inext[word[i]-'a']==NULL){
return false;
}
p=p->next[word[i]-'a'];
}
if(p->num!=0){
return true;
}else{
return false;
}
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Node* p=root;
for(int i=0;inext[prefix[i]-'a']==NULL)
return false;
p=p->next[prefix[i]-'a'];
}
return true;
}
};
BF算法基本思想:
从主串M的第一个字符开始分别与子串从开头进行比较,当发现不匹配时,主串回到这一轮的下一个字符,子串从头开始比较,直到子串所有字符都匹配,返回所在主串中的下标。
#include
#include
using namespace std;
int BF(char s[],char t[])
{
int i=0,j=0;
while((s[i]!='\0') && (t[j]!='\0')){
if(s[i]==t[j])
{
i++;
j++;
}
else{
i=i-j+1;
j=0;
}
}
if(t[j] == '\0'){
return i-j+1;
}else{
return 0;
}
}
int main()
{
char s[7]={'a','a','a','d','a','b','c'};
char t[3]={'b','c'};
int a=BF(s,t);
cout<
2.3.1 Reverse String (反转字符串)
LeetCode 344
class Solution {
public:
void reverseString(vector& s) {
int left = 0,right = s.size()-1;
while(left < right){
char t = s[left];
s[left] = s[right];
s[right] = t;
++left;
--right;
}
}
};
2.3.2 Reverse Words in a String(翻转字符串里的单词)
LeetCode 151
class Solution{
public :
string reverseWords(string s){
s +=" ";
vector v;
string ins=" ";
for(int i=0;i=0;i--){
ins +=v[i]+" ";
}
ins.erase(ins.end()-1);
swap(ins,s);
return s;
}
};
2.3.3 String to Integer (atoi)(字符串转换整数 (atoi))
LeetCode 8
class Solution {
public:
int myAtoi(string str)
{
int i = 0;
int sign = 1;
long num = 0;
while(isspace(str[i])) i++; //删除前面的空格
if(str[i]=='-' || str[i]=='+')
if(str[i++] == '-') sign *= -1; //负数变号
while(str[i]=='0') i++;
while(isdigit(str[i])) //是否是数字
{
num = 10*num + str[i++]-'0'; //转换为数字
if(num > fabs(long(INT_MIN))) break; //超过int表示范围
}
num *= sign; //数值正负
if(num < INT_MIN) return INT_MIN;
if(num > INT_MAX) return INT_MAX;
return num;
}
}
The end~