常用算法模板

BFS

单向BFS

不记录层数

while queue 不空:
    cur = queue.pop()
    for 节点 in cur的所有相邻节点:
        if 该节点有效且未访问过:
            queue.push(该节点)

作者:负雪明烛
链接:https://leetcode.cn/problems/01-matrix/solutions/203364/tao-lu-da-jie-mi-gao-dong-ti-mu-kao-cha-shi-yao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

记录层数

level = 0
while queue 不空:
    size = queue.size()
    while (size --) {
        cur = queue.pop()
        for 节点 in cur的所有相邻节点:
            if 该节点有效且未被访问过:
                queue.push(该节点)
    }
    level ++;
	
作者:负雪明烛
链接:https://leetcode.cn/problems/01-matrix/solutions/203364/tao-lu-da-jie-mi-gao-dong-ti-mu-kao-cha-shi-yao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双向BFS

// d1、d2 为两个方向的队列
// m1、m2 为两个方向的哈希表,记录每个节点距离起点的
    
// 只有两个队列都不空,才有必要继续往下搜索
// 如果其中一个队列空了,说明从某个方向搜到底都搜不到该方向的目标节点
while(!d1.isEmpty() && !d2.isEmpty()) {
    if (d1.size() < d2.size()) {
        update(d1, m1, m2);
    } else {
        update(d2, m2, m1);
    }
}

// update 为将当前队列 d 中包含的元素取出,进行「一次完整扩展」的逻辑(按层拓展)
void update(Deque d, Map cur, Map other) {}

作者:宫水三叶
链接:https://leetcode.cn/problems/word-ladder/solutions/831894/gong-shui-san-xie-ru-he-shi-yong-shuang-magjd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

排序

插入排序

void insertSort(int a[],int n){

  int i, j;
  for(i = 1; i < n; ++i){
    if(a[i] < a[i - 1]){
      int temp = a[i];
      // 依次查看前面是不是还有比自己大的元素
      for(j = i - 1; j >= 0 && a[j] > temp; --j){
        a[j + 1] = a[j];
      } // for
      a[j + 1] = temp;
    } // if
  } // for
}

折半插入排序

void insertBinarySort(int a[],int n){
  int i, j;
  for(i = 1; i < n; ++i){
    if(a[i] < a[i - 1]){
      int temp = i;
      int low = 0;
      int high = i - 1;

      // 二分查找
      while(low <= high){
        int mid = (high - low) / 2 + low;
        // 为了保证插入排序稳定性,在相等时候low = mid + 1
        if(a[mid] == temp || a[mid] < temp){
          low = mid + 1;
        }else{
          high = mid - 1;
        } // else
      } // while

      for(j = i - 1; j >= low; --j){
        a[j + 1] = a[j];
      }
      a[low] = temp;
    }
  }
}

选择排序

void selectSort(int a[], int n){
  for(int i = 0; i < n - 1; ++i){
    int min = i;
    for(int j = i + 1; j < n; ++j){
      if(a[j] < a[min]){
        min = j;
      }
      if(min != i){
        swap(a[i], a[min]);
      }
    } // for
  }
}

快速排序

int getMid(int start, int end){

  int mid = start + (end - start) / 2;
  int Sum = a[start] + a[mid] + a[end];
  int Max = max(max(a[start], a[mid]), a[end - 1]);
  int Min = min(min(a[start], a[mid]), a[end - 1]);
  int Mid = Sum - Max - Min;
  if(Mid == a[start])
    return start;
  else if(Mid == a[mid])
    return mid;
  else
    return end - 1;
}

int partition(int start, int end){
  int pos = getMid(start, end);
  int key = a[pos];
  swap(a[pos], a[end - 1]);
  int i = start, j = end - 1;

  while(i < j){
    // 两个指针轮流遍历
    for(; i < j; ++i){
      if(a[i] > key){
        a[j] = a[i];
        break;
      } // if
    } // for

    for(; i < j; --j){
      if(a[j] < key){
        a[i] = a[j];
        break;
      } // if
    } // for
  } // while
  a[i] = key;

  return i;
}

void quickSort(int start, int end){
  if(start + 1 < end){
    int pos = partition(start, end);
    quickSort(start, pos);
    quickSort(pos + 1, end);
  }
}

归并排序

void myMerge(int a[], int left, int right){

  int mid = left + (right - left) / 2;
  int nl = mid - left, nr = right - mid;
  int l[nl], r[nr];
  for(int i = 0; i < nl; ++i)
    l[i] = a[left + i];
  for(int i = 0; i < nr; ++i)
    r[i] = a[mid + i];

  int k = left, i = 0, j = 0;
  while(i < nl && j < nr && k < right){
    if(l[i] <= r[j]){
      a[k] = l[i];
      ++i, ++k;
    }else{
      a[k] = r[j];
      ++j, ++k;
    } // else
  } // while
  
  while(i < nl && k < right){
    a[k] = l[i];
    (void) (++i), ++k;
  } // while
  while(j < nr && k < right){
    a[k] = r[j];
    (void) (++j), ++k;
  } // while
}

void mergeSort(int *a, int left, int right){
  if(left + 1 < right){
    int mid = left + (right - left) / 2;
    mergeSort(a, left, mid);
    mergeSort(a, mid, right);
    myMerge(a, left, right);
  }
}

拓扑排序

模板题:

二分搜索

int bsearch_1(int left, int right)
{
    while (left < right)
    {
        int mid = (right - left) / 2 + left;
        if (check(mid)) right = mid;
        else left = mid + 1;
    }
    return left;
}

作者:林小鹿
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/955576/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
int bsearch_2(int left, int right)
{
    while (left < right)
    {
        int mid = (right - left + 1) / 2 + left;
        if (check(mid)) left = mid;
        else right = mid - 1;
    }
    return left;
}

作者:林小鹿
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/955576/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针/滑动窗口

1. 定义需要用到的变量,如快慢指针int slow = 0, int fast = 0; 输入的string s; 
Hashmap char_freq用于记录string s当中slow到fast(包含)之间所有的字母出现的频率;
int longest记录符合题目要求的最长substring长度等

2. 定义双while循环
while fast < len(s):
    char_freq[s[fast]] = char_freq.get(s[fast], 0) + 1
    ......
    ......
    while 符合slow指针移动的条件:
        char_freq[s[slow]] -= 1
        ......
        ......
        slow += 1
    if 符合某些判断条件:
        longest = max(longest, fast - slow + 1)
    fast += 1
return longest

Kruscal(含并查集)

#include <bits/stdc++.h>

#define mem(a, what) memset(a, what, sizeof(a))
#define INF 0x3f3f3f3f
#define MINF 0x3f
//#define _debug
//#define fre

using namespace std;

typedef pair<int, int> P;

struct Edge{
  int from, to, weight;

  Edge(){}

  Edge(int from, int to, int weight){
    this->weight = weight;
    this->to = to;
    this->from = from;
  }

  bool operator<(const Edge& other) const {
    return weight < other.weight;
  }
};

const int MAXN = 1000;
const int MAXM = 100000;
Edge edge[MAXM + 3];
int pre[MAXN + 3];
int n, m;
int ans;

void init(){
  for(int i = 0; i <= MAXN; ++i){
    pre[i] = i;
  }
}

void merge(int r, int x){
  int i = x, j;

  while(pre[i] != r){
    j = pre[i];
    pre[i] = r;
    i = j;
  }
}

int find(int x){
  int r = x;
  while(r != pre[r])
    r = pre[r];

  merge(r, x);

  return r;
}

bool mix(int a, int b){
  int fx = find(a), fy = find(b);

  if(fx == fy)
    return false;

  pre[fx] = fy;
  return true;
}

int main(int argc, char *argv[]){

  scanf("%d %d", &n, &m);

  for(int i = 0; i < m; ++i){
    scanf("%d %d %d", &edge[i].from, &edge[i].to, &edge[i].weight);

  }

  init();
  sort(edge, edge + m);

  for(int i = 0; i < m; ++i){
    if(mix(edge[i].from, edge[i].to)){
      ans += edge[i].weight;
    }
  }

  printf("%d\n", ans);

  return 0;
  
}

动态规划

动态规划问题总结

posted @ 2023-01-15 14:09  Frodo1124  阅读(28)  评论(0编辑  收藏  举报