1
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
1 单链表的反转如何解决,三种方法,一是使用栈,二是使用两个链表,三是使用递归
import java.util.Stack;
public class Solution {
public ListNode ReverseList(ListNode head) {
    Stack<ListNode> stack= new Stack<>();
    //把链表节点全部摘掉放到栈中
    while (head != null) {
        stack.push(head);
        head = head.next;
    }
    if (stack.isEmpty())
        return null;
    ListNode node = stack.pop();
    ListNode dummy = node;
    //栈中的结点全部出栈,然后重新连成一个新的链表
    while (!stack.isEmpty()) {
        ListNode tempNode = stack.pop();
        node.next = tempNode;
        node = node.next;
    }
    //最后一个结点就是反转前的头结点,一定要让他的next
    //等于空,否则会构成环
    node.next = null;
    return dummy;
}
}


public ListNode ReverseList(ListNode head) {
    //新链表
    ListNode newHead = null;
    while (head != null) {
        //先保存访问的节点的下一个节点,保存起来
        //留着下一步访问的
        ListNode temp = head.next;
        //每次访问的原链表节点都会成为新链表的头结点,
        //其实就是把新链表挂到访问的原链表节点的
        //后面就行了
        head.next = newHead;
        //更新新链表
        newHead = head;
        //重新赋值,继续访问
        head = temp;
    }
    //返回新链表
    return newHead;
}

public ListNode ReverseList(ListNode head) {
    //终止条件
    if (head == null || head.next == null)
        return head;
    //保存当前节点的下一个结点
    ListNode next = head.next;
    //从当前节点的下一个结点开始递归调用
    ListNode reverse = ReverseList(next);
    //reverse是反转之后的链表,因为函数reverseList
    // 表示的是对链表的反转,所以反转完之后next肯定
    // 是链表reverse的尾结点,然后我们再把当前节点
    //head挂到next节点的后面就完成了链表的反转。
    next.next = head;
    //这里head相当于变成了尾结点,尾结点都是为空的,
    //否则会构成环
    head.next = null;
    return reverse;
}

 

 

 

 

2

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1\to 2 \to 3 \to 4 \to 5 \to NULL12345NULL, m=2,n=4m=2,n=4,
返回 1\to 4\to 3\to 2\to 5\to NULL14325NULL.

双指针(两次遍历),

一次遍历(对解法一的优化)

数据范围: 链表长度 0 < size \le 10000<size1000,0 < m \le n \le size0<mnsize,链表中每个节点的值满足 |val| \le 1000val1000
要求:时间复杂度 O(n)O(n) ,空间复杂度 O(n)O(n)
进阶:时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)
import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
       // 解法一:双指针(两次遍历)
       //说明:方便理解,以下注释中将用left,right分别代替m,n节点 

    public ListNode reverseBetween (ListNode head, int m, int n) {
             //设置虚拟头节点
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;

        ListNode pre = dummyNode;
        //1.走left-1步到left的前一个节点
        for(int i=0;i<m-1;i++){
            pre = pre.next;
        }

        //2.走roght-left+1步到right节点
        ListNode rigthNode = pre;
        for(int i=0;i<n-m+1;i++){
            rigthNode = rigthNode.next;
        }

        //3.截取出一个子链表
        ListNode leftNode = pre.next;
        ListNode cur = rigthNode.next;

        //4.切断链接
        pre.next=null;
        rigthNode.next=null;

        //5.反转局部链表
        reverseLinkedList(leftNode);

        //6.接回原来的链表
        pre.next = rigthNode;
        leftNode.next = cur;
        return dummyNode.next;
    }
    //反转局部链表
    private void reverseLinkedList(ListNode head){
        ListNode pre = null;
        ListNode cur = head;
        while(cur!=null){
            //Cur_next 指向cur节点的下一个节点
            ListNode Cur_next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = Cur_next ;
        }
    }
}




import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
       // 
       //说明:方便理解,以下注释中将用left,right分别代替m,n节点 

    public ListNode reverseBetween (ListNode head, int m, int n) {
             //设置虚拟头节点
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next =head;
        ListNode pre = dummyNode;
        for(int i=0;i<m-1;i++){
            pre = pre.next;
        }

        ListNode cur = pre.next;
        ListNode Cur_next ;
        for(int i=0;i<n-m;i++){
            Cur_next = cur.next;
            cur.next = Cur_next.next;
            Cur_next .next = pre.next;
            pre.next = Cur_next ;
        }
        return dummyNode.next;
    }
}

 

 

 

 

 

 

 

 

3 sql

distinct和group by的区别, https://zhuanlan.zhihu.com/p/356383514

distinct

select distinct university from user_profile distinct去重, 

 

asc+order by

SELECT device_id,age FROM user_profile ORDER BY age ASC; 结尾加 ASC是升序,不写也行因为默认升序。 SELECT device_id,age FROM user_profile ORDER BY age desc; 结尾加 desc 是降序。 

多列排序的优先级别,左侧优先

SELECT device_id,gpa,age from user_profile order by gpa,age;默认以升序排列
SELECT device_id,gpa,age from user_profile order by gpa asc,age asc;

https://blog.csdn.net/weixin_42630109/article/details/81839638

 

--

between

1.between 在列值得某与某之间
select
device_id,
gender,
age,
university
from user_profile
WHERE
age between 20 and 23

2.用and的来连接条件范围
SELECT
device_id,
gender,
age
from user_profile
WHERE
age >= 20 and age<=23

max

  1. where筛选 复旦大学条件,因最高的gpa,进行order by gpa desc降序,取第一行的数据即可
    select gpa from user_profile
    WHERE
    university='复旦大学'
    order by gpa desc limit 1

2.where筛选 复旦大学条件,因最高的gpa,max(gpa)求出最大值也可
select
max(gpa )
from user_profile
WHERE
university='复旦大学'

 

#计算男生人数以及平均GPA#

count, avg

问题分解:

  1. 限定条件为 男性用户;
  2. 有多少人,明显是计数,count函数;
  3. 平均gpa,求平均值用avg函数;

细节问题:根据输出示例,有两个问题需要注意:

  1. 表头重命名,用as语法
  2. 浮点数的平均值可能小数点位数很多,按照示例保存一位小数,用round函数

因此完整代码呼之欲出:

1
2
3
4
select
  count(gender) as male_num,
  round(avg(gpa), 1) as avg_gpa
from user_profile where gender="male";

 

 左连接,右连接

 

算法--常见的一些算法题目

https://blog.csdn.net/Gassuih/article/details/114883968

queue 的 offer,poll,peek 方法
2022-01-04 11:51:55
  • offer() 是往队列中添加一个元素,若队列已满而仍往队列中添加,则会返回false
  • poll() 是删除队列中的第一个元素,在对空队列进行操作时,返回null
  • peek() 是输出队列的第一个元素,队列为空时,返回null

 

如何理解高并发

https://blog.csdn.net/belongtocode/article/details/107443598

高性能:qps,tps。缓存,数据库,消息,异步化

高可用:4个9。限流,降级,监控,幂等。

高扩展:合理的业务拆分