当前位置: 首页 > article >正文

【2025小白版】计算复试/保研机试模板(个人总结非GPT生成)附代码

在这里插入图片描述

一、编程语言选择

很多高校在机试中对编程语言都有明确规定,像复旦大学计算机学院就说明可选择 C、C++ 或 Java 语言答题,还支持 C11(gcc5.4),C++14(g++5.4),Java (openjdk1.8)等编译环境。这里强烈建议大家使用 C/C++,因为几乎所有高校都支持,通用性超强👍。

二、准备好模板是至关重要的

一般来说,机试都可以带书和纸质资料进入考场。所以提前把那些函数的用法和算法的模板准备好是很重要的,一方面是增加自己的信心,万一没记住还可以翻开来看一下。另外说不定考到原题或者类似的题,就可以直接秒杀了。
在这里插入图片描述机试模板PDF详细代码自取

常见头文件

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
cout << abs(a);
memset(a,-1,sizeof(a));  #include <string.h>

int转字符串

string intToString(long long x){
	string s;
	while(x){
		s += (x % 10) + '0';
		x = x / 10;
	} 	
	reverse(s.begin(),s.end());
    return s;
}

日期模板

int daytab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31
},
{0,31,29,31,30,31,30,31,31,30,31,30,31,
}
};

bool IsLeapYear(int x){
    return (x % 4 == 0&& x % 100 != 0) || (x % 400 ==0);
}
=====================================================算天数
	while(cin >> y >> m >> d){
		int sum = 0;
		for(int i = 0;i < m ;i ++){
			sum += daytab[isLeapYear(y)][i];
		}
		sum += d;
		cout << sum << endl;
	}
======================================================
    scanf("%04d%02d%02d",&y1,&m1,&d1);
======================================================
// 第n天后是什么日期
        cin >> y >> m >> d >> n;
        n = n + d;
        d = 0;
        while(n >= daytab[IsLeapYear(y)][m]){
            n -= daytab[IsLeapYear(y)][m];
            if(m == 12){
                y ++;
                m = 1;
            }else{
                m ++;
            }
        }
        d = d + n;
        if(d == 0 && m != 1){
            m --;
            d = daytab[IsLeapYear(y)][m];
        }else if(d == 0 && m == 1){
            m = 12;
            d = daytab[IsLeapYear(y)][m];
        }
        printf("%04d-%02d-%02d\n",y,m,d);
    }

二分查找(在已经有序的情况下)

bool BinarySearch(int n,int x){
	int l = 0,r = n - 1;
	while(l <= r){
		int m = (r + l) / 2;
		if(a[m] < x){
			l = m + 1;
		}else if(a[m] > x){
			r = m - 1;
		}else{
			return true;
		}
	}
	return false;
}

sort排序,重写CMP函数

bool cmp(Student x,Student y){
	if(x.score == y.score){
		return x.num < y.num; 
	}else{
		return x.score < y.score;
	}
} 

stable_sort(&stu[0],&stu[n],cmp); //重点:sort是不稳定排序,stable_sort才是稳定排序 

快速排序

void quick_sort(int q[],int l,int r){
	if(l >= r)return ;
	int x = q[(l + r) >> 1], i = l - 1,j = r + 1;
	while(i < j){
		do i ++;while(q[i] < x);
		do j --;while(q[j] > x);
		if(i < j)swap(q[i],q[j]);
	} 
	quick_sort(q,l,j);
	quick_sort(q,j + 1,r);
}

归并排序 + 逆序数对

void merge_sort(int q[],int l,int r){
	if(l >= r)return ;
	int mid = (l + r) >> 1;
	merge_sort(q,l,mid);
	merge_sort(q,mid + 1,r);
	int i = l ,j = mid + 1,k = 0;
	
	// 左右指针进行比较 
	while(i <= mid && j <= r){
		if(q[i] < q[j])temp[k ++] = q[i ++];
		else temp[k ++] = q[j ++];
	}
	// 没有分完的 
	while(i <= mid)temp[k ++] = q[i ++];
	while(j <= r)temp[k ++] = q[j ++];
	
	for(int i = l,j = 0;i <= r;i ++,j ++)q[i] = temp[j];
}
============================================================
逆序数
while(i <= mid && j <= r){
		if(q[i] > q[j]){
			temp[k ++] = q[j ++];
			sum += mid - i + 1;
		}
		else temp[k ++] = q[i ++];
	}
cout << sum << endl;

字符串处理

int index = str.find('a');

string newstr = str.substr(startIndex,count);

向量vector map queue stack

vector<int> vectore;

vectore.push_back('i');
vectore.pop_back();

for(int i = 0;i < vectore.size();i ++)

    // map自带对键排序,进行迭代
map<int,string>::iterator it;
for(it = str.begin();it != str.end();it ++){
    cout << it->second << endl;
}

queue<Animal> cats;
dogs.front().number

stack<int> s;
s.push(i);
s.pop();
s.top();
s.empty();

最大公约数、最小公倍数

int gcd(int a,int b){
    return b ? gcd(b,a % b):a;
}

// 最小公倍数
min =  (a * b) / gcd;

最长子序列和问题 + 最长公共序列

for(int i=1;i<n;i++){
            a[i]=max(a[i],a[i-1]+a[i]);
            answer=max(answer,a[i]);
        }
        cout<<answer<<endl;

for (int i = 1; i <= a.size(); i++) {
	for (int j = 1; j <= b.size(); j++) {
		if (a[i - 1] == b[j - 1]) {
			dp[i][j] = dp[i - 1][j - 1] + 1;
		}
		else {
			dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
		}
	}
}

背包问题

const int N = 1010;
int n,m;//物品数量和背包容积
int v[N],w[N];
int f[N];

int main(){
    cin >> n >> m;
    
    for(int i = 1;i <= n;i ++){
        cin >> v[i] >> w[i];
    }
    
    for(int i = 1;i <= n;i ++){
        for(int j = m;j >= v[i];j --){//2种情况
            f[j] = max(f[j],f[j - v[i]] + w[i]);//背包有空间
        }
    }
    
    cout << f[m] << endl;
    return 0;
}
// 完全
for(int i = 1;i <= n;i ++){
        for(int j = v[i];j <= m;j ++){
            f[j] = max(f[j],f[j - v[i]] + w[i]);
        }
    }

进制转化

======================================================================================
    数比较小
void convert(int n,int b){
	while(n){
		a[cnt ++] = n % b;
		n = n / b;
	}
}
	cin >> n >> b;
	convert(n,b);
	for(int i = cnt - 1;i >= 0;i --)cout << a[i];
=====================================================================================
    高精度:s原字符串,m是原进制,b是转换后的进制
string convert(string s, int m, int b) {
    string ans; 
    while (!s.empty()) {
        int k = 0; // 余数
        bool leadingZero = true; // 用于去除前导零
        string temp;
        for (int i = 0; i < s.size(); i++) {
        	// 如果是字母字符(用于大于10的进制),则转换为对应的值,如'A' -> 10, 'B' -> 11
            int digit = (isdigit(s[i]) ? s[i] - '0' : s[i] - 'A' + 10);
            int t = (k * m + digit) % b;
            int quotient = (k * m + digit) / b;
            k = t;
            if (quotient != 0 || !leadingZero) {
                temp += (quotient < 10 ? quotient + '0' : quotient - 10 + 'A');
                leadingZero = false;
            }
        }
        ans += (k < 10 ? k + '0' : k - 10 + 'A');
        s = temp;
    }
    reverse(ans.begin(), ans.end());
    return ans.empty() ? "0" : ans;
}
====================================================================================
    16进制到10进制
int CharToInt(char c){
    if(c >= '0' && c <= '9')    return c - '0';
    else return c - 'A' + 10;
}
int main() {
    string str;
    while (cin >> str) {
        int x = 0;
        for(int i = 2; i < str.length(); i ++){
            x = x * 16 + CharToInt(str[i]);
        }
        cout << x << endl;
    }
    return 0;
}

单词替换(字符串)

    getline(cin,s);
	
	cin >> a >> b;
	
	for(int i = 0;i < s.size();i ++){
		int j = i;
		string word;
		// s[j]不为空格时把他加到单词序列中,相当于split 
		while(j < s.size() && s[j] != ' ')word += s[j ++];
		i = j;
		
		if(word == a)cout << b << ' ';
		else cout << word << ' ';
	}

结构体应用

// 定义一个结构体 `point`,用来存储字符的相关信息
struct point {
    int num; // 记录字符在字符串中出现的次数
    vector<int> AA; // 记录字符在字符串中出现的位置(索引)
    bool flag = false; // 用来判断是不是该字符第一次被输出
};

int main() {
    string s; // 用来存储输入的字符串
    map<char, point> mapp; // 定义一个映射,用来存储每个字符及其对应的 `point` 结构体

    while (cin >> s) { // 逐行读取输入的字符串
        // 第一次遍历字符串,统计每个字符的出现次数
        for (int i = 0; i < s.size(); i++) {
            mapp[s[i]].num++;
        }
        
        // 第二次遍历字符串,记录每个字符的出现位置(如果出现次数大于1)
        for (int i = 0; i < s.size(); i++) {
            if (mapp[s[i]].num > 1) {
                mapp[s[i]].AA.push_back(i);
            }
        }
        
        // 第三次遍历字符串,输出每个出现次数大于1且还未被输出的字符及其出现的位置
        for (int i = 0; i < s.size(); i++) {
            if (mapp[s[i]].num > 1 && mapp[s[i]].flag == false) {
                for (int j = 0; j < mapp[s[i]].AA.size(); j++) {
                    if (j == 0)
                        printf("%c:%d", s[i], mapp[s[i]].AA[j]);
                    else
                        printf(",%c:%d", s[i], mapp[s[i]].AA[j]);
                }
                cout << endl;
                mapp[s[i]].flag = true; // 标记该字符已被输出
            }
        }
    }
    return 0;
}

约瑟夫环问题

int main() {
    int n, p, m; // n多少人,p从哪里开始,m经过多少人淘汰 
    while (cin >> n >> p >> m && (n || p || m)) {
        queue<int> children;
        for (int i = 1; i <= n; ++i) {
            children.push(i);
        }
        
        // 将队列旋转到第p个小孩开始
        for (int i = 1; i < p; ++i) {
            children.push(children.front());
            children.pop();
        }
        
        while (!children.empty()) {
            // 报数到第m个
            for (int i = 1; i < m; ++i) {
                children.push(children.front());
                children.pop();
            }
            
            // 输出当前出圈的小孩编号
            cout << children.front();
            children.pop();
            if (!children.empty()) {
                cout << ",";
            }
        }
        cout << endl;
    }
    return 0;
}

素数

bool isPrime(int n)
{
    if(n == 1 || n == 0 || n < 0)return false;  
    for(int i = 2; i <= sqrt(n); i++) 
    {
        if(n % i ==0)
            return false;
    }
    return true;
}

埃氏筛法
const int maxn = 10000000;
int prime[maxn];
bool IsPrime[maxn] = {0};//0代表都是素数
void Find_Prime(){
    IsPrime[1] = 1;//1不是素数
    int pNum = 1;
    for(int i = 2; i <= maxn; i++){
        if(!IsPrime[i])
            prime[pNum++] = i;
        for(int j = i * i; j <= maxn; j += i){
            IsPrime[j] = true;
        }
    }
}

printf("%d\n", prime[k]);

质因数+约数

    int ret = 0;
    // 从 2 开始尝试每个可能的因数,直到 sqrt(n)
    for (int i = 2; i <= sqrt(n); i++) {
        // 如果 i 是 n 的一个因数
        while (n % i == 0) {
            ret++;  // 计数器加一
            n /= i;  // 用 i 除去 n 的这个因数
        }
        // 如果 n 已经被完全分解,提前退出循环
        if (n <= 1) break;
    }
    
    // 如果存在大于 sqrt(n) 的质因数,则它只能是 n 本身
    if (n > 1) ret++;
    
    return ret;
约数
int Counter(int x){
	int count = 0; 
	int i = 1;
	for(i = 1;i * i < x;i ++){
		if(x % i == 0)count += 2;
	}
	if(i * i == x) count ++;
	return count;
}

快速幂

typedef long long LL;
LL a,n;

LL ksm(LL a, LL n){
	LL ans = 1;
	while(n){
		if(n & 1)ans *= a;//如果n的最后一位是1 
		a *= a;
		n >>= 1; //二进制去掉最后一个1,*2 
	}
	return ans;
} 

int main(){
	cin >> a >> n;
	
	cout << ksm(a,n);

高精度加减乘除

// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}

// C = A - B, 满足A >= B, A >= 0, B >= 0
vector<int> sub(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

// C = A * b, A >= 0, b >= 0
vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;

    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;
}

// A / b = C ... r, A >= 0, b > 0
vector<int> div(vector<int> &A, int b, int &r)
{
    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

KMP

// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}

// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        j = ne[j];
        // 匹配成功后的逻辑
    }
}

BFS走迷宫

#include <iostream>
#include <queue>

#define x first
#define y second

using namespace std;

typedef pair<int,int> PII;

const int N = 1e3 + 10;

int n,m;
int g[N][N];
int d[N][N];
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};

void bfs(int u){
    queue<int> q;
    q.push({1,1});
    memset(d,-1,sizeof(d));
    d[1][1] = 0;
    while(q.size()){
        PII t = q.front();
        q.pop();
        for(int i = 0;i < 4;i ++){
            int a = t.x +dx[i];
            int b = dy[i] + t.y;
            if(a < 1 || a > n || b < 1 || b > m)continue;
            if(g[a][b] == 1)continue;
            if(d[a][b] != -1)continue;
            d[a][b] = d[t.x][t.y] + 1;
            q.push({a,b});
        }
    }
}

int main(){
    cin >> n >> m;
    
    for(int i = 0;i < n;i ++){
        for(int j = 0;j < n;j ++){
            cin >> g[i][j];
        }
    }
    
    bfs();
    
    cout << d[n][m] << endl;
    return 0;
}

N皇后问题DFS

#include <iostream>

using namespace std;

const int N = 20; // 对角线元素2n-1取20防止越界
int n;
char g[N][N]; // 存储图
bool col[N],dg[N],udg[N]; // udg副对角线 diagonal  
int cnt;
 
void dfs(int x){
	if(x == n){ // 如果找到方案的话 
		for(int i = 0;i < n;i ++){
			puts(g[i]); // puts输出二维数组 输出每一行就会自动换行
		}
		puts("");
		cnt ++;
		return; // 返回调用函数进行执行 
	}
	
	// x : 行 y : 列
	for(int y = 0;y < n;y ++){
		// 按行枚举 因为每一行都需要放皇后 相当于剪枝 
		// 判断皇后是否放在这格
		if(!col[y] && !dg[x + y] && !udg[y - x + n]){
			g[x][y] = 'Q';
			col[y] = dg[x + y] = udg[y - x + n] = true;
		
			dfs(x + 1); // 找下一行
			
			// 回溯的时候恢复现场
			col[y] = dg[x + y] = udg[y - x + n] = false;
			g[x][y] = '.'; 
		} 
	} 
}
int main(){
	cin >> n;
	
	for(int i = 0;i < n;i ++){
		for(int j =0;j < n;j ++){
			g[i][j] = '.';
		}
	} 
	
	dfs(0); // 从第一行开始找[0:下标] 

	return 0;
}

链表类型

链表反转

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *cur = head, *pre = nullptr;
        while(cur != nullptr) {
            ListNode* tmp = cur->next; // 暂存后继节点 cur.next
            cur->next = pre;           // 修改 next 引用指向
            pre = cur;                 // pre 暂存 cur
            cur = tmp;                 // cur 访问下一节点
        }
        return pre;
    }
};

回文链表

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> vals;
        while (head != nullptr) {
            vals.emplace_back(head->val);
            head = head->next;
        }
        for (int i = 0, j = (int)vals.size() - 1; i < j; ++i, --j) {
            if (vals[i] != vals[j]) {
                return false;
            }
        }
        return true;
    }
};

环形链表

public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();
        while (head != null) {
            if (!seen.add(head)) {
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

排序链表

class Solution {
public:
    ListNode* sortList(ListNode* head) { 
        return mergeSort(head);
    }

    /**
     * 对给定的链表进行归并排序
    */
    ListNode* mergeSort(ListNode* head){
        // 如果链表为空或只有一个节点,无需排序直接返回
        if(!head || !head->next){
            return head;    
        }
        // 获取链表的中间节点,分别对左右子链表进行排序
        ListNode* mid = getMid(head);
        ListNode* rightSorted = mergeSort(mid->next);   // 排序右子链表
        if(mid)mid->next = nullptr;                     // 断开两段子链表
        ListNode* leftSorted = mergeSort(head);         // 排序左子链表
        return mergeTwoLists(leftSorted, rightSorted);  // 两个子链表必然有序,合并两个有序的链表
    }

    /**
     * 获取以head为头节点的链表中间节点
     * 如果链表长度为奇数,返回最中间的那个节点
     * 如果链表长度为偶数,返回中间靠左的那个节点
    */
    ListNode* getMid(ListNode* head){
        if(!head)return head;   
        ListNode* slow = head, *fast = head->next;          // 快慢指针,慢指针初始为
        while(fast != nullptr && fast->next != nullptr)     
        {
            fast = fast->next->next;    // 快指针每次移动两个节点
            slow = slow->next;          // 慢指针每次移动一个节点
        }
        return slow;    // 快指针到达链表尾部时,慢指针即指向中间节点
    }

    /**
     * 合并两个有序链表list1和list2
    */
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* dummy = new ListNode();   // 伪头节点,用于定位合并链表的头节点
        ListNode* node = dummy;             // 新链表当前的最后一个节点,初始为伪头节点
        // 直到两个链表都遍历完了,合并结束
        while(list1 != nullptr || list2 != nullptr){
            int val1 = list1 == nullptr ? 50001 : list1 -> val;   // 如果链表1已经遍历完,val1取最大值,保证链表2的节点被选择到       
            int val2 = list2 == nullptr ? 50001 : list2 -> val;   // 如果链表2已经遍历完,val2取最大值,保证链表1的节点被选择到 
            if(val1 < val2){
                // 链表1的节点值更小,加入到合并链表,并更新链表1指向的节点
                node -> next = list1;
                list1 = list1 -> next;
            }else{
                // 链表2的节点值更小,加入到合并链表,并更新链表2指向的节点
                node -> next = list2;
                list2 = list2 -> next;
            }
            node = node -> next;    // 更新合并链表当前的最后一个节点指向
        }
        return dummy -> next;       // 伪头节点的下一个节点即为合并链表的头节点
    }
};


合并两个有序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        } else if (l2 == nullptr) {
            return l1;
        } else if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};

是否含有子链表

struct Link {
    int data;
    struct Link *next;
};
#include <stdio.h>
void subList(Link *a,Link *b) {
    struct Link *la = a ,*pA = la->next, *pB = b->next;
    while (pA&&pB) {
        if (pA->data==pB->data) {//相等继续对比下一个
            pA = pA->next;
            pB = pB->next;
        }
        else {
            pB = b->next;//pb从头开始与pa对比
            la = la->next;//失败一次,la往后移动一个节点
            pA = la->next;//pa从下一个节点又开始
        }
    }
    pB == NULL ? printf("true") : printf("false");//如果pb为NULL,说明已比对完成
}
int main() {
    struct Link *a, *b;
    Link *createLink(int);
    a = createLink(0);
    b = createLink(0);
    subList(a,b);
    return 0;
}

合并链表

    /*
        有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2连接到h1之后,要求连接后的链表仍保持循环链表形式。
    */
    struct Link {
        int data;
        struct Link *next;
    };
    void linkTwoLists(Link *h1,Link *h2) {
        struct Link *p1 = h1->next, *p2 = h2->next;
        while (p1->next != h1) p1 = p1->next;//这里要去判断p1->next是否等于h1,进而判断出是否到达尾结点
        p1->next = p2;
        while (p2->next != h2) p2 = p2->next;
        p2->next = h1;
        free(h2);//释放h2
    }
    int main() {
        struct Link *h1, *h2,*p;
        Link *createSinLoopLink();
        h1 = createSinLoopLink();
        h2 = createSinLoopLink();
        linkTwoLists(h1,h2);
        p = h1->next;
        while (p!=h1) {
            printf("%d ",p->data);
            p = p->next;
        }
        return 0;
    }

输出链表倒数第K个结点

ListNode *findKthTail(ListNode *pHead, int K) {
	ListNode *p1(pHead), *p2(pHead);
	for(int i=0; i<K; ++i){
		p1 = p1-> next;
		if(!p1){
			return nullptr;
		}
	}

	while(p1){
		p1 = p1-> next;
		p2 = p2-> next;
	}
	return p2;
}

两数相加

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* first = new ListNode(0);  // 哑结点
        ListNode* last = first;
        int carry = 0;
        while(l1 or l2 or carry){
            // 相加
            int bitsum = 0;
            if(l1){
                bitsum += l1->val;
                l1 = l1->next;
            }
            if(l2){
                bitsum += l2->val;
                l2 = l2->next;
            }
            if(carry){
                bitsum += carry;
            }
            // 结果
            int digit = bitsum % 10;
            carry = bitsum / 10;
            // 链表存储
            ListNode* node = new ListNode(digit);
            last->next = node;
            last = node;
        }
        last = first->next;
        delete first;
        return last;
    }
};

计算循环链表中环的长度

int getLoopLength(ListNode *pHead) {
    ListNode *fast(pHead), *slow(pHead);
    while (fast && fast->next) {
        fast = fast->next->next;
        slow = slow->next;
        if (fast == slow) {
            break;
        }
    }
    if (!fast || !fast->next) return -1;

    int length = 1;  // 从1开始
    while (slow->next != fast) {
        slow = slow->next;
        length++;
    }
    return length;
}

先序遍历

void preorder(TreeNode *root, vector<int> &res) {
        if (root == nullptr) {
            return;
        }
        res.push_back(root->val);
        preorder(root->left, res);
        preorder(root->right, res);
    }

    vector<int> preorderTraversal(TreeNode *root) {
        vector<int> res;
        preorder(root, res);
        return res;
    }

层序遍历

vector<vector<int>> levelOrder(TreeNode* root) {
        vector <vector <int>> ret;
        if (!root) {
            return ret;
        }

        queue <TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int currentLevelSize = q.size();
            ret.push_back(vector <int> ());
            for (int i = 1; i <= currentLevelSize; ++i) {
                auto node = q.front(); q.pop();
                ret.back().push_back(node->val);
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
        }
        
        return ret;

完全二叉树的节点个数

int countNodes(TreeNode* root) {
        if(!root)return 0;
        return countNodes(root -> left) + countNodes(root -> right) + 1;
    }

每个人戴不同帽子的方案数

using LL = long long;

class Solution {
private:
    static constexpr int mod = 1000000007;
    
public:
    int numberWays(vector<vector<int>>& hats) {
        int n = hats.size();
        // 找到帽子编号的最大值,这样我们只需要求出 $f[maxhatid][2^n - 1]$ 作为答案
        int maxHatId = 0;
        for (int i = 0; i < n; ++i) {
            for (int h: hats[i]) {
                maxHatId = max(maxHatId, h);
            }
        }
        
        // 对于每一顶帽子 h,hatToPerson[h] 中存储了喜欢这顶帽子的所有人,方便进行动态规划
        vector<vector<int>> hatToPerson(maxHatId + 1);
        for (int i = 0; i < n; ++i) {
            for (int h: hats[i]) {
                hatToPerson[h].push_back(i);
            }
        }
        
        vector<vector<int>> f(maxHatId + 1, vector<int>(1 << n));
        // 边界条件
        f[0][0] = 1;
        for (int i = 1; i <= maxHatId; ++i) {
            for (int mask = 0; mask < (1 << n); ++mask) {
                f[i][mask] = f[i - 1][mask];
                for (int j: hatToPerson[i]) {
                    if (mask & (1 << j)) {
                        f[i][mask] += f[i - 1][mask ^ (1 << j)];
                        f[i][mask] %= mod;
                    }
                }
            }
        }
        
        return f[maxHatId][(1 << n) - 1];
    }
};

同构字符串

bool isIsomorphic(string s, string t) {
        if(s.size() != t.size())return false;
        unordered_map<char,char> s1;
        unordered_map<char,char> s2;
        for(int i = 0;i < s.size();i ++){
            char x = s[i],y = t[i];
            if((s1.count(x) && s1[x] != y) || (s2.count(y) && s2[y] != x))return false;
            s1[x] = y;
            s2[y] = x;
        }
        return true;
    }

因篇幅受限,如需查看完整版内容,请点击“上述的link”.


http://www.kler.cn/a/572272.html

相关文章:

  • centos和ubuntu下安装redis
  • Linux笔记---缓冲区
  • 医疗行业网络安全:目前面临哪些挑战?
  • 基于Spring Boot的企业车辆管理系统设计与实现(LW+源码+讲解)
  • Stable Diffusion 反向提示词(Negative Prompt)深度解析
  • 小迪安全25天-php-文件管理包含,写入,删除,下载,上传,遍历,安全。
  • 宝塔找不到php扩展swoole,服务器编译安装
  • Android中的Content Provider是什么以及它有哪些用途
  • 软件工程中的各种图
  • COVID-19时变SEIR传染病模型Matlab程序
  • 表访问方法:PostgreSQL 中数据更新的处理方式
  • SpringBoot获取YAML配置文件中的属性值(二):使用Environment环境组件读取值
  • Leetcode 二叉搜索树迭代器
  • SLAM文献之-DROID-SLAM: Deep Visual SLAM for Monocular, Stereo, and RGB-D Cameras
  • netframework 读取appsettings.json
  • 【练习】【链表】力扣热题100 160. 相交链表
  • CC++的内存管理
  • 网络安全ctf试题 ctf网络安全大赛真题
  • stm32(hal库)学习笔记-时钟系统
  • BS架构(笔记整理)