以题为例浅谈双指针算法

什么是双指针算法

双指针是指在遍历元素时,不是使用单个指针进行遍历而是使用两个指针进行访问,从而达到相应目的;注意这个指针不是c语言中那个指向地址的指针;

双指针分类

双指针分为对撞指针和快慢指针;

对撞指针:两个指针方向相反,例如你需要用两个指针去遍历一个数组,一个从数组起始点开始进行遍历,一个指针是从最后开始遍历;

快慢指针:快慢指针是方向相同,例如一个数组都是从数组起始的地方进行遍历或者都是从尾部进行遍历,快慢指针又称为弗洛伊德算法,兔子乌龟算法;

快慢指针常用判别链表中是否有环

接下来用题目详细介绍这两种算法

对撞指针

对撞指针常用于解决那些问题

有序数组两数之和

二分查找

三数之和(无序)

最接近的三数之和

有序数组两数之和

例题链接:. - 力扣(LeetCode)

题目描述:

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1]numbers[index2] ,则 1 <= index1 < index2 <= numbers.length

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 index2

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

示例

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

先上代码

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
            int i=0;
            int j=numbers.size()-1;
            while(i<j)
            {
                int sum=numbers[i]+numbers[j];
                if(sum<target)
                i++;
                else if(sum>target)
                j--;
                else
                return vector<int>{i+1,j+1};
            }
             return vector<int>{-1,-1};
    }
};

解释一下这段代码就是题目已经告诉我们按非递减顺序排好了,那就说明数组已经按照递增顺序排好了;接下来就是按照要求求和,这个数组右边是最大值,左边是最小值,那就设两个指针进行遍历,在这段代码中设的就是i和j,分别给i和j赋值,在这里,numbers[i]就是这个数组的最小值,numbers[j]就是这个数组的最大值,然后相加,将相加的值与目标值进行比较,如果小于目标值说明需要将值增大,就要将i向右移,因为右边的值大于左边的值,如果大于同理就要让这个值小一点,所以r向左移,如果相等说明找到了就返回;

三数之和(无序)

有人会疑惑,三数之和双指针怎么去满足,看看下面的题去解释

题目:三数之和

题目链接:. - 力扣(LeetCode)

题意:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

先看代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
        for(int first=0;first<n;first++)
        {
            if(first>0&&nums[first]==nums[first-1])
            continue;
            int third=n-1;
            int target=-nums[first];
            for(int second=first+1;second<n;second++)
            {
                if(second>first+1&&nums[second]==nums[second-1])
                continue;
                while(second<third&&nums[second]+nums[third]>target)
                {
                    third--;
                }
                if(second==third)
                break;
                if(nums[second]+nums[third]==target)
                ans.push_back({nums[first],nums[second],nums[third]});
            }
        }
        return ans;
    }
};

在此解释一下这段代码,先将数组进行排序,排完之后在设置一个vector的容器;然后就是三层循环最主要的是那两个for循环,第一个for循环循环first的指向,将first不断向前移动,这里面的双指针分别是second和third,third赋值为n-1就是将third置为数组的最右边,将目标值减去nums[first]的值,那么目标值就是second和third值之和,然后开始进行移动两个指针,如果值大于目标1值说明需要third的值向左移因为左边的值要小,往左移,移到second等于third说明所有的值都大于目标值那直接就退出最里面的for循环说明在移second也没有用了因为second的值是往右移的,值一直增大,后面的值会更大于目标值target,找到符合的值就假如到ans容器中到最后进行返回;

 二分查找

二分查找就不再举例子了,因为二分查找中本来就蕴含了双指针的思想,他本来就设两个指针,一边是在数组的最左边,一个指针指向数组最右边,所以不再说了,这属于二分算法中的一环了;

快慢指针

快慢指针有龟兔赛跑的名字,非常的亲切;

快慢指针运用的领域

快慢指针可以利用在链表中也可以运用在数组中;

运用在链表中有以下几种运用的方式

1.判断环形链表

2.找出倒数第k个结点

3.找出链表中间结点

4.找到环形链表的的入口(进阶)

5. 相交链表

1.判断环形链表

题目链接:. - 力扣(LeetCode)

题意

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

示例1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    if(head==NULL||head->next==NULL)
    return false;
    struct ListNode *slow=head,*fast=head->next;
    while(slow!=fast)
    {
        if(fast->next==NULL||fast->next->next==NULL)
        {
            return false;
        }
        fast=fast->next->next;
        slow=slow->next;
    }
    return true;
}

判断环形链表是快慢指针的典型题目,在有环链表如果它有环,快指针每次走两步,慢指针每次走一步那么有环他们必定相遇,注意一定要是快指针走两步,慢指针每次走一步,如果走别的步数可能就不能去辨别了;为什么呢?这里涉及到数学问题了,原来计算机的尽头真的是数学啊,

走一步,那么快指针比慢指针每次多走一步是1的倍数那么如何它们都会相遇;

如果快指针每次走三步那么,快指针每次比慢指针走2步,那么就不是1的倍数了,而一个奇数无论减几个偶数它都是奇数,它们就不会相遇,同样偶数也是如此,所以快慢指针中慢指针走一步而快指针走两步是最好的结果;

2.找出倒数第k个结点

题目链接:https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/description/

题意:给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt 个训练项目编号。

示例1:

输入:head = [2,4,7,8], cnt = 1
输出:8

代码:

    ListNode* trainingPlan(ListNode* head, int cnt) {
        ListNode* l,*r;
        l=r=head;
        if(head==NULL)
        return NULL;
        for(int i=0;i<cnt;i++)
        r=r->next;
        while(r!=nullptr)
        {
            r=r->next;
            l=l->next;
        }
        return l;
    }

解释一下这段代码,就是让快指针先移步k个结点(注意代码中ans就是k),然后快指针与慢指针一起移动当快指针移到空的时候,慢指针到达的位置就是倒数第k个位置(倒数第ans个位置),为什么呢? 这里需要涉及相关的数学公式列方程

假如链表的长度是n,那么在头指针到这个位置就是(n-k),那么当一个指针移动n-k个位置时就到达了倒数第k个位置,那么快指针先移动了k个位置那它剩下的就是n-k个位置,那么这时候慢指针和快指针一起移动,当快指针为空的时候,慢指针就到达了第k个位置了;

3.找出链表中间结点

题目链接:. - 力扣(LeetCode)

题意:

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

示例:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

代码:

    ListNode* deleteMiddle(ListNode* head) {
   if (head->next==nullptr) {  

        return nullptr;  

    }
    ListNode* r=head;
    ListNode* l=head;
    ListNode* pre=nullptr;
        while(l&&l->next)
        {
            l=l->next;
            l=l->next;
            pre=r;
            r=r->next;
        }
        pre->next=pre->next->next;
        return head;
    }

解析一下这段代码,这个就是快指针走两步,慢指针走一步,那么当快指针走完之后,慢指针刚好到达中点;

下面举两个例子分别分析奇数和偶数个数的情况

当数是奇数个

1->2->3->4->5

快指针和慢指针都从1开始走,当快指针走到5的时候,慢指针刚好到达3也就是中间位置,这个时候快指针的条件就是r->next==NULL

当数的个数是偶数个时

1->2->3->4->5->6

快指针和慢指针都从1开始走,当快指针走到6后面的时候,慢指针刚好到达4满足条件的位置,这个时候,快指针的条件就是r==NULL;

所以这段代码整体的意思就影刃而解了

4.找到环形链表入口

题目链接:. - 力扣(LeetCode)

题意:

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

示例:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

代码

    ListNode *detectCycle(ListNode *head) {
        ListNode *slow=head,*fast=head;
        while(fast!=nullptr){
        slow=slow->next;
        if(fast->next==nullptr)
        return nullptr;
        fast=fast->next->next;
        if(fast==slow){
                    fast=head;
        while(fast!=slow)
        {
            fast=fast->next;
            slow=slow->next;
        }
        return slow;
        }
        }
        return nullptr;
    }

在这里先解释一下这道题的原理:把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili

这个视频解释的非常清楚不理解的可以看看,因为我这里没有图就不做多的解释了,本来想尝试画一下图感觉太抽象了;

解释一下这段代码吧,就是先看看这fast或者fast->next是不是为空,因为fast一下挑两格,所以有可能是fast为空也有可能fast->next为空,之后就是fast一下走两步,slow每次走一步,当slow和fast第一次相遇时将fast置为head,在此相遇时就是入口,这里还是数学公式的推导,视频里很详细;

5.相交链表

提名链接:. - 力扣(LeetCode)

题意:

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

  • intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
  • listA - 第一个链表
  • listB - 第二个链表
  • skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
  • skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数

评测系统将根据这些输入创建链式数据结构,并将两个头节点 headAheadB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案

示例1

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

代码

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (headA == nullptr || headB == nullptr) {
        return nullptr;
    }

    // 计算链表 A 和链表 B 的长度
    int lenA = 0, lenB = 0;
    ListNode *tempA = headA, *tempB = headB;
    while (tempA != nullptr) {
        lenA++;
        tempA = tempA->next;
    }
    while (tempB != nullptr) {
        lenB++;
        tempB = tempB->next;
    }

    // 将指针移动到使它们的长度相等的位置上
    tempA = headA;
    tempB = headB;
    if (lenA > lenB) {
        int diff = lenA - lenB;
        while (diff-- > 0) {
            tempA = tempA->next;
        }
    } else {
        int diff = lenB - lenA;
        while (diff-- > 0) {
            tempB = tempB->next;
        }
    }

    // 遍历链表直到找到交点
    while (tempA != nullptr && tempB != nullptr) {
        if (tempA == tempB) {
            return tempA;
        }
        tempA = tempA->next;
        tempB = tempB->next;
    }

    return nullptr; // 没有交点
}

解析一下这段代码

先通过循环求出两个链表的长度,然后让比较长的那个链表,先走一段距离使两个链表到最后的结点的长度是相同的,然后遍历两个链表,相等了就是相遇了就表示有交点,否则就没有交点;

题例

多说无益,以题见真章

这段题目是综合进阶的题目

逛画展

题目链接:逛画展 - 洛谷

题意:

博览馆正在展出由世上最佳的 mm 位画家所画的图画。

游客在购买门票时必须说明两个数字,aa 和 bb,代表他要看展览中的第 aa 幅至第 bb 幅画(包含 a,ba,b)之间的所有图画,而门票的价钱就是一张图画一元。

Sept 希望入场后可以看到所有名师的图画。当然,他想最小化购买门票的价格。

请求出他购买门票时应选择的 a,ba,b,数据保证一定有解。

若存在多组解,输出 aa 最小的那组

输入格式:

第一行两个整数 n,mn,m,分别表示博览馆内的图画总数及这些图画是由多少位名师的画所绘画的。

第二行包含 nn 个整数 aiai​,代表画第 ii 幅画的名师的编号。

输出格式:

一行两个整数 a,ba,b。

输入输出样例

输入

12 5
2 5 3 1 3 2 4 1 1 5 4 3

输出

2 7

代码如下

#include<iostream>
using namespace std;
int cnt,ans,n,m,a[1000005],b[1000005],ansl,ansr;
void I(int x)
{
	if(b[x]==0)
	{
		cnt++;
	}
	b[x]++;
}
void D(int x)
{
	if(b[x]==1)
	{
		cnt--;
	}
	b[x]--; 
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	ans=n;
	for(int l=1,r=1;r<=n;r++)
	{
		I(a[r]);
		while(true)
		{
			D(a[l]);
			if(cnt==m)
			l++;
			else
			{
				I(a[l]);
				break;
			}	
		}
		if(cnt==m&&r+1-l<ans)
		{
			ans=r+1-l;
			ansl=l;
			ansr=r;
		}
	}
	if(ansl!=0)
	cout<<ansl<<" "<<ansr;
	else
	cout<<1<<" "<<ans;
	return 0;
}

这是一道快慢指针类型的题目;

解释一下代码,题目要求的是将全部画家的画包含在内并且要求包含的画最小,注意它只能按照顺序去看而不能跳级去看,那么就定义两个指针,两个指针都指向数组的开始,然后先向数组中添加一副画,然后r是一直向后移动的,然后就是将l这副画删除然后去判断是否满足条件,如果满足条件就将l指向的这幅画删除,如果不行在把这幅画添上,然后就这样一直判断最后输出相应的数组,其实我感觉这道题不是明确的快慢指针;

在进阶

统计子矩阵

这道题是用了二维数组,需要将它压缩为一维数组之后,在进行指针移动

题目链接:[蓝桥杯 2022 省 B] 统计子矩阵 - 洛谷

题意:

给定一个 N×MN×M 的矩阵 AA,请你统计有多少个子矩阵 (最小 1×11×1, 最大 N×M)N×M) 满足子矩阵中所有数的和不超过给定的整数 KK。

输入格式:

第一行包含三个整数 N,MN,M 和 KK。

之后 NN 行每行包含 MM 个整数, 代表矩阵 AA。

输出格式:

一个整数代表答案。

输入输出样例

输入

3 4 10
1 2 3 4
5 6 7 8
9 10 11 12

输出

19

代码如下

#include<iostream>
#define int long long
using namespace std;
int a[505][505],s[505][505],ans;
int b[505];
signed main()
{
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
	}
	for(int j=1;j<=m;j++)
	{
		for(int i=1;i<=n;i++)
		s[i][j]=s[i-1][j]+a[i][j];
	}  //求行之间的前缀和
	for(int ii=1;ii<=n;ii++)
	{
		for(int i=ii;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				b[j]=s[i][j]-s[ii-1][j];
			}
			int l=1,r=0,sum=0;
			while(r<m)
			{
				r++;
				sum+=b[r];
				if(sum<=k)
				ans+=(r-l+1);
				else
				{
					while(sum>k){
					sum-=b[l];
					l++;
					}
					ans+=(r-l+1);
				}
			}
		}
	}
	cout<<ans;
	return 0;
}

解释一下这段代码算是快慢指针中的一道类型题吧

先将二维数组按列求出前缀和,然后用三个嵌套循环,前两个循环用于行之间的相减,最后一个循环用于列之间的相减,就是行之间对应进行相减就是s[1][1]-s[0][1]以此类推,将它们的值加入到一个一维数组当中,它这个循环就是先是第一行的值减第零行的值,之后就是将第二行的值减去第零行的值.....之后第二行减第一行,第三行减去第一行;之后得到一个一维数组,在用两个指针,进行遍历,第一个指针在前面如果两个位置在的数组的数相减小于k那就加上r-l+1,为啥加一因为r从0开始的,也就是快指针从0开始的而慢指针是从0开始的,为什么是r-l,注意这个数组代表的前缀和,所以当这两个区间相加小于目标值那么原来这个数组它本身的值就小于目标值;

双指针就先到这了,自我感觉总结的并不好,感觉有的知识点知道但是不知道这么说,我在研究研究将它完善完善;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/476084.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ServletConfig和ServletContext

ServletConfig接口 在Servlet运行期间&#xff0c;需要一些配置信息&#xff0c;这些信息都可以在WebServlet注解的属性中配置。当Tomcat初始化一个Servlet时&#xff0c;会将该Servlet的配置信息封装到一个ServletConfig对象中&#xff0c;通过调用init(ServletConfig config…

手写一个跳表,跪了。。。

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团、蚂蚁、得物的面试资格&#xff0c;遇到很多很重要的相关面试题&#xff1a; 手写一个跳表&#xff1f; redis为什…

蓝桥刷题--四元组问题和肖恩的投球游戏加强版

1.四元组问题 我的这个代码有点问题&#xff0c;我也找不出来&#xff0c;哪位大佬指正一下 // 四元组问题 //思路 // 是否存在 a < b < c < d, 使得nums[d] < nums[c] < nums[a] < nums[b] //分别维护二元组 (a, b) 和 (c, d), 对合法 b 维护前缀 max 的 n…

QT_day2:页面设计使用ui

1、自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。&#xff08;不要使用课堂上的图片和代码&#xff0c;自己发挥&#xff0c;有利于后面项目的完成&#xff09; 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关设置&#xff0c…

C++多线程都可以对同一个全局变量读写,不设置锁应该没关系吧?

C多线程都可以对同一个全局变量读写&#xff0c;不设置锁应该没关系吧&#xff1f; 是这个意思吗&#xff1a;某个线程只操作一个二进制位&#xff0c;不会有其他线程和它抢着操作同一个二制进位&#xff0c;这种情况下&#xff0c;是否需要锁&#xff1f; 在开始前我有一些资…

openGauss学习笔记-248 openGauss性能调优-使用Plan Hint进行调优-Plan Hint调优概述

文章目录 openGauss学习笔记-248 openGauss性能调优-使用Plan Hint进行调优-Plan Hint调优概述248.1 功能描述248.2 支持范围248.3 注意事项248.4 示例 openGauss学习笔记-248 openGauss性能调优-使用Plan Hint进行调优-Plan Hint调优概述 Plan Hint为用户提供了直接影响执行计…

小白也可以轻松学大模型 RAG:FlagEmbedding 重排序

RAG模型已经取得了显著的进展&#xff0c;但其性能仍然受到排序质量的限制。在实践中&#xff0c;我们发现重排序技术能够有效地改善排序的效果&#xff0c;从而进一步提升RAG模型在问答任务中的表现。 重排序的作用 与传统的嵌入模型不同&#xff0c;重排序器&#xff08;rera…

Tomcat启动报错 因为在清除过期缓存条目后可用空间仍不足

在Tomcat部署路径下的./conf/context.xml配置文件的标签内添加如下内容&#xff1a; <Resources cachingAllowed"true" cacheMaxSize"100000" />

【高频SQL题目进阶版】1440.计算布尔表达式的值

错误答案&#xff1a; 我一开始以为&#xff0c;既然都能拿到值了&#xff0c; 那么把它们合并起来就可以了。后来发现不行。。 1 concat concat(v1.value ,operator ,v2.value) 它不是一个条件&#xff0c;而只是一个字符串 。 而if (condition, true_value, false_value)…

【Leetcode】top 100 链表

基础知识补充 单向链表结构&#xff1a;item存储数据 next指向下一结点地址 head保存首地址 class Node(object): # 创建结点def __init__(self, item): self.item item # item存放数据元素self.next None # next是下一个…

ginblog博客系统/golang+vue

ginblog博客系统 前台&#xff1a; 后台&#xff1a; Gitee的项目地址&#xff0c;点击进入下载 注意&#xff1a; 数据库文件导入在model里面&#xff0c;直接导入即可。 admin和front前后台系统记住修改https里的地址为自己的IP地址&#xff1a; front同上。

考研数学老师怎么选❓看这一篇就够了

张宇、汤家凤、武忠祥、李永乐、杨超、王式安、方浩这些老师都有自己擅长的细分 比如张宇老师&#xff0c;杨超&#xff0c;汤家凤&#xff0c;武忠祥老师的高数讲的很好&#xff0c;李永乐老师是线代的神&#xff0c;王式安、方浩概率论讲的很好&#xff0c;所以对于不同的学…

数据库学习记录(二)多表设计与多表查询

一对多 一对多时候&#xff0c;一张表内的一个数据可能对应着其他表内的多个数据&#xff0c;例如一个部门内有多个员工&#xff0c;但是公司里不只一个部门&#xff0c;也不止一个员工&#xff0c;这个时候就是一对多的情况&#xff0c;这个时候可以绑定一个外键&#xff0c;…

递归与回溯

先来看问题&#xff0c;其实问题不难理解&#xff1a; n 皇后问题研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 上图为 8 皇后问题的一种解法。 给定一个整数 n&#xff0c;返回所有不同的 n 皇后问题的解决方案。 每一种解法包…

基于Springboot的在线装修管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的在线装修管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

elk7.11.2离线安装

elk与jdk自行搜索下载 package(离线安装包)目录&#xff1a;/home/elk-pak /home/jdk8-pak 安装目录&#xff1a;/usr/local/ jdk8安装 最好查看一下是否存在原服务器自带openJDK rpm -qa|grep java # 有就执行下边卸载命令 无拉倒 rpm -e --nodeps jdk-xxx# 解压jdk8安装包…

你的电脑打不开摄像头问题

我一直以为我电脑上的摄像头老是打不开是因为硬件不匹配的问题。知道我发现了我的拯救者Y7000的机身盘边的“摄像头开关”按钮。。。 我去&#xff0c;你的摄像头开关按钮怎么设置在机身旁边啊。。。。 —————————————————————— 2024年3月21日更新记录&a…

zookeeper快速入门二:zookeeper基本概念

本文是zookeeper系列之快速入门中的第二篇&#xff0c;欢迎大家观看与指出不足。 目录 一、zookeeper的存储结构 二、什么是znode 三、znode节点的四种类型 四、权限控制ACL&#xff08;Access Control List&#xff09; 五、事件监听watcher 一、zookeeper的存储结构 z…

【C++】---string的模拟

【C】---string的模拟 一、string类实现1.string类的构造函数2.swap&#xff08;&#xff09;函数3.拷贝构造函数4.赋值运算符重载5.析构6.迭代器7.operator[ ]8.size9.c_str&#xff08;&#xff09;10.reserve&#xff08;&#xff09;11.resize&#xff08;&#xff09;12.p…