<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[LeiGerのBlog]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/thunder_666</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; thunder_666]]></copyright><item><title><![CDATA[两条链表相交一些列问题]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/118759579</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/118759579</guid><author>thunder_666</author><pubDate>Thu, 15 Jul 2021 14:57:09 +0800</pubDate><description><![CDATA[public class LoopNode {

    //首先得判断这条链表有没有环
    public Node getLoopNode(Node head){
        //有环的话必须上三个节点以上，因此
        if (head == null || head.next == null || head.next.next == null){
            return null;
        }
        //链表有环情况，使用快慢指针
        Nod]]></description><category></category></item><item><title><![CDATA[反转单链表中的部分链表]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114489371</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114489371</guid><author>thunder_666</author><pubDate>Sun, 07 Mar 2021 16:54:39 +0800</pubDate><description><![CDATA[给定一个单向链表的头节点 head，以及两个整数 from 和 to，在单向链表上把第 from 个节
点到第 to 个节点这一部分进行反转

大致思路：
1、找到要反转部分链表的前一个节点fPre和后一个节点tPos，把反转的部分先反转，然后重新连接fPre和tPos；
2、若fPre为null，说明反转部分包括头节点，则返回的是反转部分的最后一个节点，即反转后的头结点，若不为空，则返回旧的头节点。
public Node reversePart(Node head,int from,int to){
.]]></description><category></category></item><item><title><![CDATA[反转单向链表和反转双向链表]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114489206</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114489206</guid><author>thunder_666</author><pubDate>Sun, 07 Mar 2021 16:51:10 +0800</pubDate><description><![CDATA[反转单向链表和反转双向链表

单向链表

具体代码

public static Node reverseList(Node head){
    Node pre = null;
    Node next = null;
    while (head != null){
        next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    return pre;
}
.]]></description><category></category></item><item><title><![CDATA[删除链表的中间节点和 a/b 处的节点]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114399590</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114399590</guid><author>thunder_666</author><pubDate>Fri, 05 Mar 2021 15:51:57 +0800</pubDate><description><![CDATA[删除链表的中间节点和 a/b 处的节点

首先是删除中间节点
链表长度为n，
n = 0, 不删除；
n = 1, 不删除；
n = 2, 删除第 1 个节点；
n = 3, 删除第 2 个节点；
n = 4, 删除第 2个节点；
n = 5, 删除第 3 个节点；
n = 6, 删除第 3 个节点；
n = 7, 删除第 4 个节点；
总结：从链表长度大于等于2时，每增加两个节点，删除节点后移一位。

具体代码

public static Node removeMidNode(Node head) {.]]></description><category></category></item><item><title><![CDATA[在单链表和双链表中删除倒数第K个节点]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114398806</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114398806</guid><author>thunder_666</author><pubDate>Fri, 05 Mar 2021 15:36:33 +0800</pubDate><description><![CDATA[在单链表和双链表中删除倒数第K个节点

先看单链表
如果链表为空或者K值小于1，直接返回即可，除此之外，让链表从头走到尾，每走一步，K值减一，如下图：

走到链表尾时:


当K&gt;0，说明没有倒数第K个节点，因此直接返回原链表即可；


当K=0，说明链表刚好有K个节点，删除倒数第K个节点就是删除第一个节点，因此返回第二个节点，即head.next;


当K&lt;0，要找到删除节点的前一个节点，需要：
​		1、重新从头节点开始走，每移动一步，k值加1；


​	           2、当k=.]]></description><category></category></item><item><title><![CDATA[打印有序链表的相同部分]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114398719</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114398719</guid><author>thunder_666</author><pubDate>Fri, 05 Mar 2021 15:33:44 +0800</pubDate><description><![CDATA[打印有序链表的相同部分

首先是有序链表，所以从两个链表的头开始遍历进行判断：

如果head1的值&lt;head2的，则移动head1；
如果head1的值&gt;head2的，则移动head2；
如果head1的值=head2的，则打印这个值，然后head1和head2同时往下移动；


具体代码

public class Node {
    public int value;
    public Node next;
    public Node(int data){
        th.]]></description><category></category></item><item><title><![CDATA[删除链表中指定节点]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114398114</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114398114</guid><author>thunder_666</author><pubDate>Fri, 05 Mar 2021 15:23:15 +0800</pubDate><description><![CDATA[删除链表中指定节点

思路：利用其他结构（这里利用栈结构）存放链表中除要删除的节点外的其他节点。依次将链表元素放入栈中，当遇到要删除的元素时跳过，最后将栈中元素重新连接成链表。

具体代码

public class removeValue {
    public static class Node{
        public int val;
        public Node next;
        public Node(int val){
            this.val =.]]></description><category></category></item><item><title><![CDATA[重建二叉树]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114366732</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114366732</guid><author>thunder_666</author><pubDate>Thu, 04 Mar 2021 13:55:06 +0800</pubDate><description><![CDATA[根据前序遍历和中序遍历结果重建二叉树

思路：
1、前序遍历的第一个数字为原二叉树根节点的值；
2、遍历中序序列，找到根节点位置，根节点左边序列即为左子树所有节点，右边序列即为右子树所有节点；
3、用同样的方法（上面两个步骤）对剩下的小序列进行操作，即一个递归的过程。


具体代码

public class TreeNode {
    TreeNode left;
    TreeNode right;
    int value;
    public TreeNode(int value){
  .]]></description><category></category></item><item><title><![CDATA[二叉树神级遍历方法--Morris遍历]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114343650</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114343650</guid><author>thunder_666</author><pubDate>Thu, 04 Mar 2021 00:56:57 +0800</pubDate><description><![CDATA[Morris遍历
morris遍历可以将额外空间复杂度降到O(1)，而常规的递归或者非递归遍历额外空间复杂度都是O(h)。常规的递归或者非递归遍历其实也用到了栈结构，在处理完子节点之后可以回到父节点，然而对于二叉树这种结构，都是从父节点指向子节点，所以子节点指向父节点通常使用栈结构来实现。
​		morris遍历避免使用栈结构来实现子节点到父节点，而是利用二叉树最下面一层节点指向null节点的指针指向上面某一个节点。比如二叉树最下面一层某个节点没有右孩子，那么该节点的right指针就指向空，这些指针被叫做空]]></description><category></category></item><item><title><![CDATA[求最大子矩阵的大小]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114292923</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114292923</guid><author>thunder_666</author><pubDate>Tue, 02 Mar 2021 19:53:23 +0800</pubDate><description><![CDATA[给定一个整型矩阵 map，其中的值只有 0 和 1 两种，求其中全是 1 的所有矩形区域中，最大的矩形区域为 1 的数量。

比如：

map为矩阵，红框内即为所求，一共有6个1，返回值为6。
解题思路：
将问题转化为单调栈结构处理。
1、遍历矩阵每一行元素，统计以当前行作为底的情况下，每个位置往上的 1的数量。使用高度数组 height 来表示。

遍历到第一行时，height={1,0,1,1}；
遍历到第二行时，height={2,1,2,2}；
遍历到第三行时，height={3,2,3,0}；
.]]></description><category></category></item><item><title><![CDATA[单调栈--找出数组中任意元素左右两边最近且比它小的元素位置]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114287270</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114287270</guid><author>thunder_666</author><pubDate>Tue, 02 Mar 2021 15:57:12 +0800</pubDate><description><![CDATA[给定一个不含有重复值的数组 arr，找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i]小的位置。返回所有位置相应的信息。

比如：
输入： arr = [3,4,1,5,6,2,7]
返回：{[-1, 2], [0, 2], [-1, -1], [2, 5], [3, 5], [2, -1], [5, -1]}
解题思路：
这个题目利用单调栈结构可以使时间复杂度降低到O(N)。首先题目是没有重复值的数组，注意，如果是有重复值的数组稍有区别。
1、先准备一个栈，用来存放所给数组元素的位置；
.]]></description><category></category></item><item><title><![CDATA[数据结构与算法--栈与队列]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/114007515</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/114007515</guid><author>thunder_666</author><pubDate>Wed, 24 Feb 2021 08:39:07 +0800</pubDate><description><![CDATA[栈与队列1、设计一个能获取当前栈的最小值的栈
1、设计一个能获取当前栈的最小值的栈

设计一个能获取当前栈的最小值的栈。

大致思路：
1、申请两个栈，一个普通栈stackData，一个能获取最小值的栈stackMin；
2、给两个栈中同时压入数据，压数规则：同时给两个栈压入数据，当要压入的数比stackMin栈顶的元素小时，将该数同时压入两栈，如果要压入的数大于stackMin栈顶的元素小时，将该数压入stackData中，将stackMin栈顶的数重新再压入stackMin，具体细节详见代码注释。
举例]]></description><category></category></item><item><title><![CDATA[23种设计模式之观察者模式]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/112852167</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/112852167</guid><author>thunder_666</author><pubDate>Tue, 19 Jan 2021 21:06:12 +0800</pubDate><description><![CDATA[观察者模式 (Observer)

观察者属于行为型模式，其目的就是定义对象间的一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被自动更新。
画图简单分析一下观察者模式一步一步的演化过程：
1、图一，最简单的两个观察者A、B监听一个主题Subject；

2、由于主题直接耦合观察者，因此产生了图二模式；

3、由于图二中主题不具有复用性，因此产生了图三模式；

4、形成最终版，其中：
Subject：被观察的对象接口，一个Subject可以有多个IObserver；
NewsP.]]></description><category></category></item><item><title><![CDATA[23种设计模式之代理模式--动态代理]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/112727414</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/112727414</guid><author>thunder_666</author><pubDate>Sun, 17 Jan 2021 00:39:39 +0800</pubDate><description><![CDATA[代理模式（Proxy）

代理模式就是为其他对象提供一种代理功能以控制对被代理对象的访问，其作用就是通过一个中间层达到间接访问目标对象的目的。
代理模式分为静态代理和动态代理
静态：由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。
动态：在程序运行时运用反射机制动态创建而成。
2、动态代理
在上一节中的静态代理中，一个代理只能代理一种类型，而且是在编译器就已经确定被代理的对象。而动态代理是在运行时，通过反射机制实现动态代理，并且能够代理各种类型的对象.]]></description><category></category></item><item><title><![CDATA[23种设计模式之代理模式--静态代理]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/112727400</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/112727400</guid><author>thunder_666</author><pubDate>Sun, 17 Jan 2021 00:35:41 +0800</pubDate><description><![CDATA[代理模式（Proxy）

代理模式就是为其他对象提供一种代理功能以控制对被代理对象的访问，其作用就是通过一个中间层达到间接访问目标对象的目的。
代理模式分为静态代理和动态代理
静态：由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。
动态：在程序运行时运用反射机制动态创建而成。
1、静态代理
静态代理的实现比较简单，代理类通过实现与目标对象相同的接口，并在类中维护一个代理对象。通过构造器塞入目标对象，赋值给代理对象，进而执行代理对象实现的接口方法，并实.]]></description><category></category></item><item><title><![CDATA[这种方式实现的字典序简直不要太简单!]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/107998640</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/107998640</guid><author>thunder_666</author><pubDate>Fri, 14 Aug 2020 10:21:46 +0800</pubDate><description><![CDATA[字典序

什么是字典序？

举个例子

​给定一个字符串数组strs={“ba”,“b”}，可以将这些字符串进行任意顺序的拼接，然而得到的所有情况中只有一种是字典序最小的字符串拼接顺序。
​拿到这种题目首先想到的是可以将所有的strs按照字典序排序，然后将串起来的结果返回，但是这种方式是错误的，按照这种思路得到上述例子的结果是bba，而正确答案是bab。因此这里提供了另外一种思路。假如要比较两个字符串，可以比较将两个字符串起来之后比较其字典序，得到较小的字典序排序，将最后的结果全部串起来就是最终答案。

.]]></description><category></category></item><item><title><![CDATA[设计一个能够获取栈中最小值的栈。]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/107874806</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/107874806</guid><author>thunder_666</author><pubDate>Sat, 08 Aug 2020 09:25:54 +0800</pubDate><description><![CDATA[设计一个栈

要求：支持 push，pop，top 操作，并能在常数时间内检索到栈中最小元素。

示例

public Stack&lt;Integer&gt; stackMin = new Stack&lt;Integer&gt;();
stackMin.push(-3);
stackMin.push(10);
stackMin.push(-32);
stackMin.getMin();--&gt;返回-32
stackMin.pop();
stackMin.top();
stackMin.getMin.]]></description><category></category></item><item><title><![CDATA[两句话总结8锁问题]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/107400569</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/107400569</guid><author>thunder_666</author><pubDate>Fri, 17 Jul 2020 09:23:00 +0800</pubDate><description><![CDATA[1、被synchronized 修饰的方法，锁的对象是方法的调用者也就是实际new的对象，先调用的先执行！执行sleep（）方法的线程并不会释放锁。
2、只要方法被 static 修饰，锁的对象就是 Class模板对象,这个则全局唯一！

...]]></description><category></category></item><item><title><![CDATA[轻松了解Volatile关键字]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/107386542</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/107386542</guid><author>thunder_666</author><pubDate>Thu, 16 Jul 2020 16:41:58 +0800</pubDate><description><![CDATA[Volatile关键字

Volatile是java虚拟机提供的轻量级的同步机制。

1、保证可见性

可见性：举个例子，有三个线程A、B、C，假设A线程想要修改主内存中的一个数据num，因为每个线程都有自己的工作内存，想要修改数据的话，需要将num获得放到自己的工作内存，然后修改完成再返回给主内存。num在修改之前等于5，A线程修改之后变为8，当B线程或C线程再去拿num数据时，获得的是8而不是5，这就是保证了可见性。总结一句话就是，某一线程修改数据后，要立马通知其他线程自己修改了！
public cl.]]></description><category></category></item><item><title><![CDATA[HashMap系列之重要方法源码详解]]></title><link>https://blog.youkuaiyun.com/thunder_666/article/details/107286886</link><guid>https://blog.youkuaiyun.com/thunder_666/article/details/107286886</guid><author>thunder_666</author><pubDate>Sat, 11 Jul 2020 16:35:16 +0800</pubDate><description><![CDATA[**	HashMap 中重要的构造方法：**

1、构造一个空的 HashMap，默认初始容量（16）和默认负载因子（0.75）。
public HashMap() {
   this.loadFactor = DEFAULT_LOAD_FACTOR; // 将默认的加载因子0.75赋值给loadFactor，并没有创建数组
}

2、 构造一个具有指定的初始容量和默认负载因子（0.75）HashMap。
 // 指定“容量大小”的构造函数
  public HashMap(int initialCapa.]]></description><category></category></item></channel></rss>