面试常见代码整理

Posted ITAK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试常见代码整理相关的知识,希望对你有一定的参考价值。

会一直更新

1. 快速排序:

1.1 基本代码

int base(int l, int r) 
    int x = a[l];
    while(l < r) 
        while(l<r && a[r]>=x) r--;
        a[l] = a[r];
        while(l<r && a[l]<=x) l++;
        a[r] = a[l];
    
    a[l] = x;
    return l;

void quick_sort(int l, int r) 
    if(l >= r) return ;
    int id = base(l, r);
    quick_sort(l, id-1);
    quick_sort(id+1, r);

1.2 快排优化

  1. 对数组进行随机洗牌
	auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
	mt19937 mt_rand(seed);
	shuffle(a, a+n, mt_rand);
  1. 取基准值的时候不默认以l取,而是随机取下标
  2. 三数取中法
int select_mid(int l, int r) 
    int m = (l + r)>>1;
    if(a[l] < a[m]) 
        if(a[r] > a[m]) return m;
        if(a[l] < a[r]) return r;
        return l;
    
    else 
        if(a[r] < a[m]) return m;
        if(a[r] > a[l]) return l;
        return r;
    

int base(int l, int r) 
    int tmp = select_mid(l, r);
    swap(a[tmp], a[l]);
    int x = a[l];
    while(l < r) 
        while(l<r && a[r]>=x) r--;
        a[l] = a[r];
        while(l<r && a[l]<=x) l++;
        a[r] = a[l];
    
    a[l] = x;
    return l;

2. 翻转链表

ListNode* ReverseList(ListNode* head) 
	if(!head || !head->next) return head;
	ListNode *now = head->next, *pre = head;
	head->next = NULL;
	while(now) 
		ListNode* tmp = now->next;
		now->next = pre;
		pre = now;
		now = tmp;
	
	return pre;

3. 归并排序

void base(int l, int m, int r) 
	int i = l, j = m+1;
	vector<int> c;
	while(i<=m && j<=r) 
		if(a[i] < a[j]) c.push_back(a[i++]);
		else c.push_back(a[j++]);
	
	while(i <= m) c.push_back(a[i++]);
	while(j <= r) c.push_back(a[j++]);
	for(int i=0; i<c.size(); i++) a[i+l] = c[i];

void merge_sort(int l, int r) 
	if(l >= r) return ;
	int m = (l + r) >> 1;
	merge_sort(l, m);
	merge_sort(m+1, r);
	base(l, m, r);

4. 最长上升子序列

dp[i] 表示以 a[i]结尾的LIS的长度。

int *a = new int[n];
for(int i=1; i<n; i++) 
	for(int j=0; j<i; j++) 
		if(a[j] < a[i]) dp[i] = max(dp[i], dp[j]+1);
	

delete []a;

5. 二叉搜索树(BST)

struct Node 
    int val;
    struct Node *left, *right;
    Node(int x):val(x), left(NULL), right(NULL);
;
bool isValidBST(Node *root, Node *Min, Node *Max) 
    if(root == NULL) return true;
    if(Max && root->val >= Max->val) return false;
    if(Min && root->val <= Min->val) return false;
    return isValidBST(root->left, Min, root) && isValidBST(root->right, root, Max);

// 判断树是否是二叉搜索树
bool isBST(Node *root) 
    return isValidBST(root, NULL, NULL);


// 判断一个数是否属于二叉搜索树
bool inBST(int x, Node *root) 
    if(root == NULL) return false;
    if(x == root->val) return true;
    if(x > root->val) return inBST(x, root->right);
    if(x < root->val) return inBST(x, root->left);


// 在BST中插入一个数
Node* insertNode(Node* root, int x) 
    if(root == NULL) return new Node(x);
    if(root->val > x) root->left =  insertNode(root->left, x);
    if(root->val < x) root->right = insertNode(root->right, x);
    return root;


// 在BST中删除一个数
Node* delNode(Node* root, int x) 
    if(root == NULL) return root;
    if(root->val == x) 
        if(root->left==NULL) root = root->right;
        if(root->right==NULL) root = root->left;
        Node* tmp = root->right;
        while(tmp->left) tmp = tmp->left;
        root->val = tmp->val;
        root->right = delNode(root->right, tmp->val);
    
    else if(root->val > x) root->left = delNode(root->left, x);
    else root->right = delNode(root->right, x);
    return root;

6.堆排序

// 构造大根堆(从小到大排序)

void heap_insert(int *a, int ind) 
    int pa = (ind-1)>>1;
    while(pa>=0 && a[pa]<a[ind]) 
        swap(a[pa], a[ind]);
        ind = pa;
        pa = (ind-1)>>1;
    

void heap_handler(int *a, int ind, int n) 
    int lch = 2*ind+1; //较大的那个节点
    while(lch < n) 
        if(lch+1<n && a[lch]<a[lch+1]) lch += 1;
        if(a[ind] >= a[lch]) break;
        swap(a[ind], a[lch]);
        ind = lch;
        lch = 2*ind+1;
    

void heap_sort(int *a, int n) 
    for(int i=n-1; i>=0; i--) 
        heap_handler(a, 0, i+1);
        swap(a[0], a[i]);
    

int main() 
    int n; cin>>n;
    int *a = new int [n];
    for(int i=0; i<n; i++) cin>>a[i];
    for(int i=1; i<n; i++) heap_insert(a, i);
    //更快
    //for(int i=n/2-1; i>=0; i--) heap_handler(a, i, n);
    heap_sort(a, n);
    for(int i=0; i<n; i++) cout<<a[i]<<endl;
    delete []a;
    return 0;


7. LRU

class LRUCache 
int cnt;
list<pair<int, int>> l;
unordered_map<int, list<pair<int, int>>::iterator> mp;
public:
    LRUCache(int n) 
        this->cnt = n;
    

    int get(int key) 
        auto it = mp.find(key);
        if(it == mp.end()) return -1;
        int value = it->second->second;
        put(key, value);
        return value;
    

    void put(int key, int value) 
        auto it = mp.find(key);
        if(it == mp.end()) 
            if(l.size() == cnt) 
                auto tmp = l.back();
                l.pop_back();
                auto it2 = mp.find(tmp.first);
                mp.erase(it2);
            
        
        else 
            l.erase(it->second);
        
        l.push_front(make_pair(key, value));
        mp[key] = l.begin();
    
;
int main() 
    LRUCache *lru = new LRUCache(4);
    cout<<lru->get(1)<<endl;
    return 0;


8. mt19937随机数

auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt_rand(time(0));
int size = r-l+1;
int rand_num = l+mt_rand()%size;

9. N个元素的全排列

void dfs(int* a, int n, int k) 
    if(k == n) return;
    for(int i=k; i<n; i++) 
        swap(a[i], a[k]);
        dfs(a, n, k+1);
        swap(a[i], a[k]);
    

以上是关于面试常见代码整理的主要内容,如果未能解决你的问题,请参考以下文章

面试必备 | 常见C++笔试面试题整理

再次爆肝熬夜整理Python编程工具面试题库学习资料总集,结尾自取免费分享

吐血整理,互联网大厂最常见的 1120 道 Java 面试题(带答案)整理

2021年面试,整理全网初中高级常见Java面试题附答案

常见Android面试题及答案(详细整理)

前端面试题及答案整理(转)