数据结构与算法-链表

单向链表(带哨兵)

public class SinglyLinkedList {
    
    private Node head = new Node(Integer.MIN_VALUE, null); // 定义一个哨兵节点作为头部节点,避免对头节点进行特殊处理
    
    // 节点类,包含值和指向下一个节点的引用
    private static class Node { 
        int value; // 存储节点的值
        Node next; // 指向下一个节点的引用

        public Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }
    }
    
    // 查找指定索引处的节点,使用-1作为起始索引来兼容哨兵节点
    private Node findNode(int index) {
        int i = -1; // 从-1开始以适应哨兵节点
        for(Node curr = this.head; curr != null; curr = curr.next, i++) {
            if(i == index) {
                return curr;
            }
        }
        return null; // 如果索引超出范围,则返回null
    }
    
    // 查找最后一个节点
    private Node findLast() {
        Node curr;
        for(curr = this.head; curr.next != null;) { // 遍历直到找到最后一个节点
            curr = curr.next;
        }
        return curr; // 返回最后一个节点
    }
    
    // 在链表末尾添加新节点
    public void addLast(int value) {
        Node last = findLast();
        last.next = new Node(value, null);
    }
    
    // 在指定索引位置插入新节点
    public void insert(int index, int value) {
        Node prev = findNode(index - 1); // 找到前一个节点
        if(prev != null) {
            prev.next = new Node(value, prev.next); // 插入新节点
        } else {
            throw illegalIndex(index); // 如果索引不合法则抛出异常
        }
    }
    
    // 删除指定索引位置的节点
    public void remove(int index) {
        Node prev = findNode(index - 1); // 找到要删除节点的前一个节点
        Node curr;
        if(prev != null && (curr = prev.next) != null) { // 确保prev和curr都不为null
            prev.next = curr.next; // 删除当前节点
        } else {
            throw illegalIndex(index); // 如果索引不合法则抛出异常
        }
    }
    
    // 在链表头部添加新节点
    public void addFirst(int value) {
        this.head.next = new Node(value, this.head.next);
    }
    
    // 创建一个非法索引异常
    private IllegalArgumentException illegalIndex(int index) {
        return new IllegalArgumentException(String.format("index [%d] 不合法%n", index));
    }
}

双向链表(带哨兵)

public class DoublyLinkedListSentinel {

    // 节点类,包含指向前一个和后一个节点的引用以及存储的值
    static class Node {
        Node prev; // 指向前一个节点
        int value; // 存储节点的值
        Node next; // 指向下一个节点

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    private final Node head; // 哨兵头节点
    private final Node tail; // 哨兵尾节点

    // 构造函数,初始化哨兵头节点和尾节点,并将它们连接起来
    public DoublyLinkedListSentinel() {
        head = new Node(null, 666, null); // 头部哨兵节点,值为666
        tail = new Node(null, 888, null); // 尾部哨兵节点,值为888
        head.next = tail;
        tail.prev = head;
    }

    // 查找指定索引处的节点,从头节点开始查找
    private Node findNode(int index) {
        int i = -1; // 从-1开始以适应哨兵节点
        for (Node p = head; p != tail; p = p.next, i++) {
            if (i == index) {
                return p;
            }
        }
        return null; // 如果索引超出范围,则返回null
    }

    // 在链表头部添加新节点
    public void addFirst(int value) {
        insert(0, value);
    }

    // 删除链表中的第一个节点
    public void removeFirst() {
        remove(0);
    }

    // 在链表末尾添加新节点
    public void addLast(int value) {
        Node pre = tail.prev; // 获取当前最后一个实际节点
        Node added = new Node(pre, value, tail); // 创建新节点并插入到末尾
        pre.next = added;
        tail.prev = added;
    }

    // 删除链表中的最后一个节点
    public void removeLast() {
        Node removed = tail.prev; // 获取当前最后一个实际节点
        if (removed == head) { // 如果没有实际节点(只有哨兵)
            throw illegalIndex(0);
        }
        Node prev = removed.prev; // 获取前一个节点
        prev.next = tail; // 更新前一个节点的next指向尾哨兵
        tail.prev = prev; // 更新尾哨兵的prev指向新的最后一个实际节点
    }

    // 在指定索引位置插入新节点
    public void insert(int index, int value) {
        Node prev = findNode(index - 1); // 找到要插入位置的前一个节点
        if (prev == null || prev.next == tail) { // 确保前一个节点存在且不是尾哨兵
            throw illegalIndex(index);
        }
        Node next = prev.next; // 获取前一个节点的下一个节点
        Node inserted = new Node(prev, value, next); // 创建新节点并插入
        prev.next = inserted;
        next.prev = inserted;
    }

    // 删除指定索引位置的节点
    public void remove(int index) {
        Node prev = findNode(index - 1); // 找到要删除节点的前一个节点
        if (prev == null || prev.next == tail) { // 确保前一个节点存在且不是尾哨兵
            throw illegalIndex(index);
        }
        Node removed = prev.next; // 获取要删除的节点
        Node next = removed.next; // 获取要删除节点的下一个节点
        prev.next = next; // 更新前一个节点的next指向
        next.prev = prev; // 更新下一个节点的prev指向
    }

    // 创建一个非法索引异常
    private IllegalArgumentException illegalIndex(int index) {
        return new IllegalArgumentException(String.format("index [%d] 不合法%n", index));
    }
}

环形链表(带哨兵)

public class DoublyLinkedListSentinel {

    // 节点类,包含指向前一个和后一个节点的引用以及存储的值
    static class Node {
        Node prev;  // 指向前一个节点
        int value;  // 存储节点的值
        Node next;  // 指向下一个节点

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    private final Node sentinel; // 哨兵节点,用于简化边界条件处理

    // 构造函数,初始化哨兵节点,使其形成一个自循环的环
    public DoublyLinkedListSentinel() {
        sentinel = new Node(null, -1, null); // 初始化哨兵节点,值为-1
        sentinel.next = sentinel;           // 将哨兵节点的next指向自己
        sentinel.prev = sentinel;           // 将哨兵节点的prev指向自己
    }

    // 在链表头部添加新节点
    public void addFirst(int value) {
        Node next = sentinel.next;          // 获取当前第一个实际节点
        Node prev = sentinel;               // 哨兵节点作为前一个节点
        Node added = new Node(prev, value, next); // 创建新节点并插入到头部
        prev.next = added;                  // 更新哨兵节点的next指向新节点
        next.prev = added;                  // 更新第一个实际节点的prev指向新节点
    }

    // 在链表末尾添加新节点
    public void addLast(int value) {
        Node prev = sentinel.prev;          // 获取当前最后一个实际节点
        Node next = sentinel;               // 哨兵节点作为下一个节点
        Node added = new Node(prev, value, next); // 创建新节点并插入到末尾
        prev.next = added;                  // 更新最后一个实际节点的next指向新节点
        next.prev = added;                  // 更新哨兵节点的prev指向新节点
    }

    // 删除链表中的第一个节点
    public void removeFirst() {
        Node removed = sentinel.next;       // 获取第一个实际节点
        if (removed == sentinel) {          // 如果链表为空,抛出异常
            throw new IllegalArgumentException("非法操作:链表为空");
        }
        Node a = sentinel;                  // 哨兵节点作为前一个节点
        Node b = removed.next;              // 第二个实际节点作为下一个节点
        a.next = b;                         // 更新哨兵节点的next指向第二个实际节点
        b.prev = a;                         // 更新第二个实际节点的prev指向哨兵节点
    }

    // 删除链表中的最后一个节点
    public void removeLast() {
        Node removed = sentinel.prev;       // 获取最后一个实际节点
        if (removed == sentinel) {          // 如果链表为空,抛出异常
            throw new IllegalArgumentException("非法操作:链表为空");
        }
        Node a = removed.prev;              // 获取倒数第二个实际节点
        Node b = sentinel;                  // 哨兵节点作为下一个节点
        a.next = b;                         // 更新倒数第二个实际节点的next指向哨兵节点
        b.prev = a;                         // 更新哨兵节点的prev指向倒数第二个实际节点
    }

    // 根据值查找节点
    private Node findNodeByValue(int value) {
        Node p = sentinel.next;             // 从第一个实际节点开始遍历
        while (p != sentinel) {             // 遍历直到回到哨兵节点
            if (p.value == value) {         // 如果找到目标值,返回该节点
                return p;
            }
            p = p.next;                     // 继续遍历下一个节点
        }
        return null;                        // 如果没有找到,返回null
    }

    // 根据值删除节点
    public void removeByValue(int value) {
        Node removed = findNodeByValue(value); // 查找要删除的节点
        if (removed != null) {              // 如果找到了节点
            Node prev = removed.prev;       // 获取前一个节点
            Node next = removed.next;       // 获取后一个节点
            prev.next = next;               // 更新前一个节点的next指向后一个节点
            next.prev = prev;               // 更新后一个节点的prev指向前一个节点
        }
    }
}

反转单向链表-Leetcode 206

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

 方法一:

public ListNode reverseList(ListNode o1) {
    ListNode n1 = null;
    ListNode p = o1;
    while (p != null) {
        n1 = new ListNode(p.val, n1);
        p = p.next;
    }
    return n1;
}

方法二:

public ListNode reverseList(ListNode head) {
		       ListNode p=head;
		       if(p!=null || p.next!=null) {
		    	   return p;
		       }
		       ListNode last=reverseList(p.next);
		       p.next.next=p;
		       p.next=null;
		       return last;
		    }

根据值删除节点-Leetcode 203

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

 方法一:

public ListNode removeElements(ListNode head, int val) {
		ListNode sential=new ListNode(-1,head);
		ListNode p1=sential;
		ListNode p2;
		while((p2=p1.next)!=null) {
			if(p2.val==val) {
				p1.next=p2.next;
			}else {
				p1=p1.next;
			}
		}
		return sential.next;
		
}

方法二:

public ListNode removeElements(ListNode head, int val) {
    if (head == null) {
        return null;
    }
    if (head.val == val) {
        return removeElements(head.next, val);
    } else {
        head.next = removeElements(head.next, val);
        return head;
    }
}

删除倒数节点-Leetcode 19

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

方法一:

public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode sentinel=new ListNode(-1,head);
        recursion(sentinel, n);
        return sentinel.next;
    }
public int recursion(ListNode p,int n) {
	if(p==null) {
		return 0;
	}
	int nth=recursion(p.next, n);
	if(nth==n) {
		p.next=p.next.next;
	}
	return nth+1;
}

方法二:

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode s = new ListNode(-1, head);
    ListNode p1 = s;
    ListNode p2 = s;
    for (int i = 0; i < n + 1; i++) {
        p2 = p2.next;
    }
    while (p2 != null) {
        p1 = p1.next;
        p2 = p2.next;
    }
    p1.next = p1.next.next;
    return s.next;
}

有序链表去重-Leetcode 83

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]
输出:[1,2]

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

 方法一:

public ListNode deleteDuplicates(ListNode head) {
    if(head==null || head.next==null) {
    	return head;
    }
    ListNode p1=head;
    ListNode p2;
    while((p2=p1.next)!=null) {
    	if(p1.val==p2.val) {
    		p1.next=p2.next;
    	}else {
			p1=p1.next;
		}
    }
    return head;
}

方法二:

public ListNode deleteDuplicates(ListNode p) {
    if (p == null || p.next == null) {
        return p;
    }
    if(p.val == p.next.val) {
        return deleteDuplicates(p.next);
    } else {
        p.next = deleteDuplicates(p.next);
        return p;
    }
}

有序链表去重-Leetcode 82

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

示例 1:

输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

示例 2:

输入:head = [1,1,1,2,3]
输出:[2,3]

 方法一:

public ListNode deleteDuplicates(ListNode p) {
    if (p == null || p.next == null) {
        return p;
    }
    if (p.val == p.next.val) {
        ListNode x = p.next.next;
        while (x != null && x.val == p.val) {
            x = x.next;
        }
        return deleteDuplicates(x);
    } else {
        p.next = deleteDuplicates(p.next);
        return p;
    }
}

方法二:

public ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }

    ListNode s = new ListNode(-1, head);
    ListNode p1 = s;
    ListNode p2;
    ListNode p3;
    while ((p2 = p1.next) != null && (p3 = p2.next) != null) {
        if (p2.val == p3.val) {
            while ((p3 = p3.next) != null 
                   && p3.val == p2.val) {
            }
            p1.next = p3;
        } else {
            p1 = p1.next;
        }
    }
    return s.next;
}

合并有序链表-Leetcode 21

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

 方法一:

public ListNode mergeTwoLists(ListNode p1, ListNode p2) {
    ListNode s = new ListNode(-1, null);
    ListNode p = s;
    while (p1 != null && p2 != null) {
        if (p1.val < p2.val) {
            p.next = p1;
            p1 = p1.next;
        } else {
            p.next = p2;
            p2 = p2.next;
        }
        p = p.next;
    }
    if (p1 != null) {
        p.next = p1;
    }
    if (p2 != null) {
        p.next = p2;
    }
    return s.next;
}

方法二:

public ListNode mergeTwoLists(ListNode p1,ListNode p2){
    if (p2==null){
        return p1;
    }
    if(p1==null){
        return p2;
    }
    if (p1.val<p2.val){
        p1.next=mergeTwoLists(p1.next,p2);
        return p1;
    }else{
        p2.next=mergeTwoLists(p1,p2.next);
        return p2;
    }
}

合并多个有序链表-Leetcode 23

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

public ListNode mergeKLists(ListNode[] lists) {
    if (lists.length == 0) {
        return null;
    }
    return split(lists, 0, lists.length - 1);
}

public ListNode split(ListNode[] lists, int i, int j) {
    System.out.println(i + " " + j);
    if (j == i) {
        return lists[i];
    }
    int m = (i + j) >>> 1;
    return mergeTwoLists(
        split(lists, i, m),
        split(lists, m + 1, j)
    );
}
public ListNode mergeTwoLists(ListNode p1,ListNode p2){
    if (p2==null){
        return p1;
    }
    if(p1==null){
        return p2;
    }
    if (p1.val<p2.val){
        p1.next=mergeTwoLists(p1.next,p2);
        return p1;
    }else{
        p2.next=mergeTwoLists(p1,p2.next);
        return p2;
    }
}

查找链表中间节点-Leetcode 876

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。

示例 2:

输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
public ListNode middleNode(ListNode head) {
    ListNode p1 = head;	// 慢指针,中间点
    ListNode p2 = head;	// 快指针
    while (p2 != null && p2.next != null) {
        p1 = p1.next;
        p2 = p2.next;
        p2 = p2.next;
    }
    return p1;
}

回文链表-Leetcode 234

给你一个单链表的头节点 head ,请你判断该链表是否为

回文链表

。如果是,返回  true ;否则,返回  false 。

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false
public boolean isPalindrome(ListNode head) {
    if(head==null || head.next==null) {
    	return true;
    }
    ListNode p1=head;
    ListNode p2=head;
    ListNode o1=p1;
    ListNode n1=null;
    while(p2!=null && p2.next!=null) {
    	p1=p1.next;
    	p2=p2.next;
    	p2=p2.next;
    	
    	o1.next=n1;
    	n1=o1;
    	p1=o1;
    }
    if(p2!=null) {
    	p1=p1.next;
    }
    while(n1!=null) {
    	if(n1.val!=p1.val) {
    		return false;
    	}
    	p1=p1.next;
    	n1=n1.next;
    }
    return true;
}

环形链表-Leetcode 141

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

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

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

示例 1:

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

示例 2:

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

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

public boolean hasCycle(ListNode head) {
    ListNode h = head; // 兔
    ListNode t = head; // 龟
    while (h != null && h.next != null) {
        t = t.next;
        h = h.next.next;
        if(h == t){
            return true;
        }
    }
    return false;
}

环形链表-Leetcode 142

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

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

不允许修改 链表。

    示例 1:

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

    示例 2:

    输入:head = [1,2], pos = 0
    输出:返回索引为 0 的链表节点
    解释:链表中有一个环,其尾部连接到第一个节点。
    

    示例 3:

    输入:head = [1], pos = -1
    输出:返回 null
    解释:链表中没有环。
    

    提示:

    • 链表中节点的数目范围在范围 [0, 104] 内
    • -105 <= Node.val <= 105
    • pos 的值为 -1 或者链表中的一个有效索引

    public ListNode detectCycle(ListNode head) {
        ListNode t=head;
        ListNode h=head;
        while(h!=null && h.next!=null) {
        	t=t.next;
        	h=h.next.next;
        	if(t==h) {
        		t=head;
        		while(true) {
        			if(h==t) {
        				return h;
        			}
        			h=h.next;
        			t=t.next;
        		}
        	}
        }
        return null;
    }

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

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

    相关文章

    剪辑学习整理

    文章目录 1. 剪辑介绍 1. 剪辑介绍 剪辑可以干什么&#xff1f;剪辑分为哪些种类&#xff1f; https://www.bilibili.com/video/BV15r421p7aF/?spm_id_from333.337.search-card.all.click&vd_source5534adbd427e3b01c725714cd93961af 学完剪辑之后如何找工作or兼职&#…

    自动驾驶数据集三剑客:nuScenes、nuImages 与 nuPlan 的技术矩阵与生态协同

    目录 1、引言 2、主要内容 2.1、定位对比&#xff1a;感知与规划的全维覆盖 2.2、数据与技术特性对比 2.3、技术协同&#xff1a;构建全栈研发生态 2.4、应用场景与评估体系 2.5、总结与展望 3、参考文献 1、引言 随着自动驾驶技术向全栈化迈进&#xff0c;Motional 团…

    快速提取Excel工作簿中所有工作表的名称?

    大家好&#xff0c;我是小鱼。 在Excel表格中如何快速提取工作簿中所有工作表的名称&#xff1f;这个问题在日常工作中也经常遇到&#xff0c;比如说经常使用的INDIRECT函数跨工作表汇总或者制作类似于导航的工作表快捷跳转列表&#xff0c;就需要每个工作表的名称。如果工作表…

    【数据结构】(7) 栈和队列

    一、栈 Stack 1、什么是栈 栈是一种特殊的线性表&#xff0c;它只能在固定的一端&#xff08;栈顶&#xff09;进行出栈、压栈操作&#xff0c;具有后进先出的特点。 2、栈概念的例题 答案为 C&#xff0c;以C为例进行讲解&#xff1a; 第一个出栈的是3&#xff0c;那么 1、…

    从运输到植保:DeepSeek大模型探索无人机智能作业技术详解

    DeepSeek&#xff0c;作为一家专注于深度学习与人工智能技术研究的企业&#xff0c;近年来在AI领域取得了显著成果&#xff0c;尤其在无人机智能作业技术方面展现了其大模型的强大能力。以下是从运输到植保领域&#xff0c;DeepSeek大模型探索无人机智能作业技术的详解&#xf…

    qt部分核心机制

    作业 1> 手动将登录项目实现&#xff0c;不要使用拖拽编程 并且&#xff0c;当点击登录按钮时&#xff0c;后台会判断账号和密码是否相等&#xff0c;如果相等给出登录成功的提示&#xff0c;并且关闭当前界面&#xff0c;发射一个跳转信号&#xff0c;如果登录失败&#…

    【Spring】什么是Spring?

    什么是Spring&#xff1f; Spring是一个开源的轻量级框架&#xff0c;是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者…

    【专题】2024-2025人工智能代理深度剖析:GenAI 前沿、LangChain 现状及演进影响与发展趋势报告汇总PDF洞察(附原数据表)

    原文链接&#xff1a;https://tecdat.cn/?p39630 在科技飞速发展的当下&#xff0c;人工智能代理正经历着深刻的变革&#xff0c;其能力演变已然成为重塑各行业格局的关键力量。从早期简单的规则执行&#xff0c;到如今复杂的自主决策与多智能体协作&#xff0c;人工智能代理…

    oCam:免费且强大的录屏软件

    今天给大家推荐一个非常好的录屏软件。几乎可以满足你日常工作的需求。而且软件完全免费&#xff0c;没有任何的广告。 oCam&#xff1a;免费且强大的录屏软件 oCam是一款功能强大的免费录屏软件&#xff0c;支持屏幕录制、游戏录制和音频录制等多种模式&#xff0c;能够满足不…

    spring学习(spring 配置文件详解)

    一 了解如何创建基本的spring 配置文件 步骤 1 导入 spring-context 依赖 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context&l…

    C++Primer学习(2.2)

    2.2 变量 变量提供一个具名的、可供程序操作的存储空间。C中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围&#xff0c;以及变量能参与的运算。对C程序员来说,“变量(variable)”和“对象(object)”一般可以互换使用。 术…

    无须付费,安装即是完全版!

    不知道大家有没有遇到过不小心删掉了电脑上超重要的文件&#xff0c;然后急得像热锅上的蚂蚁&#xff1f; 别担心&#xff0c;今天给大家带来一款超给力的数据恢复软件&#xff0c;简直就是拯救文件的“救星”&#xff01; 数据恢复 专业的恢复数据软件 这款软件的界面设计得特…

    【Ubuntu】本地部署Deep Seek(深度求索)大模型的保姆级教程 | 详细教程

    杭州深度求索人工智能基础技术研究有限公司(简称“深度求索”或“DeepSeek”)&#xff0c;成立于2023年&#xff0c;DeepSeek是一家专注通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与应用&#xff0c;经营范围包括技术服务、技术开发、软…

    Ollama + AnythingLLM + Deepseek r1 实现本地知识库

    1、Ollama&#xff1a;‌是一个开源的大型语言模型 (LLM)服务工具&#xff0c;旨在简化在本地运行大语言模型的过程&#xff0c;降低使用大语言模型的门槛‌。 2、AnythingLLM&#xff1a;是由Mintplex Labs Inc. 开发的一款全栈应用程序&#xff0c;旨在构建一个高效、可定制、…

    网络安全治理架构图 网络安全管理架构

    网站安全攻防战 XSS攻击 防御手段&#xff1a; - 消毒。 因为恶意脚本中有一些特殊字符&#xff0c;可以通过转义的方式来进行防范 - HttpOnly 对cookie添加httpOnly属性则脚本不能修改cookie。就能防止恶意脚本篡改cookie 注入攻击 SQL注入攻击需要攻击者对数据库结构有所…

    如何利用maven更优雅的打包

    最近在客户现场部署项目&#xff0c;有两套环境&#xff0c;无法连接互联网&#xff0c;两套环境之间也是完全隔离&#xff0c;于是问题就来了&#xff0c;每次都要远程到公司电脑改完代码&#xff0c;打包&#xff0c;通过网盘&#xff08;如果没有会员&#xff0c;上传下载慢…

    mysql 不是内部或外部命令,也不是可运行的程序或批处理文件

    mysql 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件 前言描述1、&#x1f331;环境变量配置&#xff08;高级系统设置&#xff09;&#xff1a;2、&#x1f331;环境变量配置&#xff08;系统属性&#xff09;&#xff1a;3、&#x1f331;环境变量配置&…

    常用数据结构之String字符串

    字符串 在Java编程语言中&#xff0c;字符可以使用基本数据类型char来保存&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 操作字符串常用的有三种类&#xff1a;String、StringBuilder、StringBuffer 接下来看看这三类常见用…

    RabbitMQ 消息顺序性保证

    方式一&#xff1a;Consumer设置exclusive 注意条件 作用于basic.consume不支持quorum queue 当同时有A、B两个消费者调用basic.consume方法消费&#xff0c;并将exclusive设置为true时&#xff0c;第二个消费者会抛出异常&#xff1a; com.rabbitmq.client.AlreadyClosedEx…

    使用LLaMA Factory踩坑记录

    前置条件&#xff1a;电脑显卡RTX 4080 问题&#xff1a;LLaMA-Factory在运行的时候&#xff0c;弹出未检测到CUDA的报错信息 结论&#xff1a;出现了以上的报错&#xff0c;主要可以归结于以下两个方面&#xff1a; 1、没有安装GPU版本的pytorch&#xff0c;下载的是CPU版本…