2021-6-4笔记01

Posted 轻舟一曲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-6-4笔记01相关的知识,希望对你有一定的参考价值。

笔记01

_11_数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1:

输入: [7,5,6,4]
输出: 5

限制:

0 <= 数组长度 <= 50000

package LeetCode;

import org.junit.Test;
import sun.plugin2.gluegen.runtime.CPU;

import java.util.Arrays;

public class _11_数组中的逆序对 {
    /*
    归并排序:在合并的时候进行统计
    * */
    public int reverseCount=0;
    public int reversePairs(int[] nums){
        if (nums==null||nums.length==0) return 0;
        copy=new int[nums.length];
        mergeSort(nums,0,nums.length-1);
        return reverseCount;
    }
    //分
    public void mergeSort(int[] nums,int s,int e){
        if (s>=e) return;
        //[0,mid],[mid+1,e]
        int mid=(s+e)>>1;
        //后序遍历
        mergeSort(nums,s,mid);
        mergeSort(nums,mid+1,e);
        merge(nums,s,mid,e);
    }
    //合并:需要用到辅助数组,双指针
    public int[] copy=null;
    public void merge(int[] nums,int s,int mid,int e){
        //复制数组
        int i=s;
        int j=mid+1;
        for (;i<=mid;i++) copy[i]=nums[i];
        for (;j<=e;j++) copy[j]=nums[j];
        int k=s;
        i=s;
        j=mid+1;
        for (;i<=mid&&j<=e;k++){//双指针,两份数组已经有序
            if (copy[i]>copy[j]){
                nums[k]=copy[j];
                j++;
                reverseCount+=mid-i+1;
            }
            else {//不存在逆序
                nums[k]=copy[i];
                i++;
            }
        }
        //处理两数组剩余部分
        for (;i<=mid;i++) nums[k++]=copy[i];
        for (;j<=e;j++) nums[k++]=copy[j];
    }




    @Test
    public void test(){
       int[] nums={4,5,6,7};
        int i = reversePairs(nums);
        System.out.println(i);
    }


}

_12_两链表的第一个公共节点

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表:

在节点 c1 开始相交。

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。

注意:

如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

package LeetCode;

import java.util.ArrayDeque;

public class _12_两链表的第一个公共节点 {
    public class ListNode {
       int val;
       ListNode next;
       ListNode(int x) {
           val = x;
           next = null;
       }
    }
    /*
    两种方法:
    方法一:逆向思维,从后开始往前比较,要用到栈,O(m+n) O(m)
    方法二:快慢指针
    * */
    public ListNode getIntersectionNode01(ListNode headA, ListNode headB) {
       if (headA==null||headB==null) return null;
        ArrayDeque<ListNode> dequeA = new ArrayDeque<>();
        ArrayDeque<ListNode> dequeB = new ArrayDeque<>();
        ListNode A=headA;
        ListNode B=headB;
        while (A!=null){
            dequeA.addFirst(A);
            A=A.next;
        }
        while (B!=null){
            dequeB.addFirst(B);
            B=B.next;
        }
        ListNode temp=null;
        while (!dequeA.isEmpty()&&!dequeB.isEmpty()){
            if (dequeA.getFirst()!=dequeB.getFirst()){//有个bug就是当只有一个节点时不进这个判断
                break;
            }
            temp=dequeA.removeFirst();
            dequeB.removeFirst();
        }
        return temp;
    }

    public ListNode getIntersectionNode(ListNode headA, ListNode headB){
        if (headA==null||headB==null) return null;
        int countA=0;
        int countB=0;
        ListNode A=headA;
        ListNode B=headB;
        while (A!=null){
            countA++;
            A=A.next;
        }
        while (B!=null){
            countB++;
            B=B.next;
        }
        A=headA;
        B=headB;
        ListNode common=null;
        if (countA>countB){
            for (int i = 0; i < countA - countB; i++) {
                A=A.next;
            }
            while (A!=null){
                if (A==B){
                    common=A;
                    break;
                }
                A=A.next;
                B=B.next;
            }
        }
        else {
            for (int i = 0; i < countB - countA; i++) {
                B=B.next;
            }
            while (A!=null){
                if (A==B){
                    common=A;
                    break;
                }
                A=A.next;
                B=B.next;
            }
        }
        return common;
    }
}

_13_一个数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

限制:

0 <= 数组长度 <= 50000

package LeetCode;

import org.junit.Test;

public class _13_一个数字在排序数组中出现的次数 {
    /*
    用二分查找算法找到第一个k和最后一个k出现的位置
    * */
    @Test
    public void  test(){
        int[] a={2,2};
        int search = search(a, 2);
        System.out.println(search);
    }

    public int search(int[] nums, int target) {
        if (nums==null) return 0;
        if (nums.length==0) return 0;
        int first=getFirstK(nums,0,nums.length-1,target);
        int last=getLastK(nums,0,nums.length-1,target);
        //如果没有k
        if (first==-1&&last==-1) return 0;
        //如果有k
        else if (first==last) return 1;
        else return last-first+1;
    }
    public int getFirstK(int[] nums,int s,int e,int target){
        int mid=0;
        while (s<=e){
            mid=(s+e)>>1;
            if (nums[mid]>target) e=mid-1;
            else if (nums[mid]<target) s=mid+1;
            else {
                if (mid-1>=0&&nums[mid-1]==target) e=mid-1;
                else break;
            }
        }
        if (s>e) mid=-1;
        return mid;
    }
    public int getLastK(int[] nums,int s,int e,int target){
        int mid=0;
        while (s<=e){
            mid=(s+e)>>1;
            if (nums[mid]>target) e=mid-1;
            else if (nums[mid]<target) s=mid+1;
            else {
                if (mid+1<=nums.length-1&&nums[mid+1]==target) s=mid+1;
                else break;
            }
        }
        if (s>e) mid=-1;
        return mid;
    }

}

_14_0到n减1中缺失的数字

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:

输入: [0,1,3]
输出: 2
示例 2:

输入: [0,1,2,3,4,5,6,7,9]
输出: 8

限制:

1 <= 数组长度 <= 10000

package LeetCode;

public class _14_0到n减1中缺失的数字 {
    /*
    方法一:先求出0~n-1的和(n-1)*n/2,再求数组,做差即可  O(N)
    方法二:利用数组递增  二分  找出第一个数组元素与下标不同的
    * */
    public int missingNumber(int[] nums) {
        if (nums==null) return -1;
        if (nums.length==0) return -1;
        int s=0;
        int e=nums.length-1;
        int mid=0;
        while (s<=e){
            mid=(s+e)>>1;
            if (mid==nums[mid]) s=mid+1;
            else if (mid!=nums[mid]){
                if (mid-1>=0&&mid-1!=nums[mid-1]) e=mid-1;
                else break;//找出第一个不等
            }
        }
        //程序有个bug,就是[0] 输出0
        if (mid==nums[mid]) mid=mid+1;
        return mid;
    }
}

_15_二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第k大的节点。

示例 1:

输入: root = [3,1,4,null,2], k = 1
3
/
1 4

2
输出: 4
示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/
3 6
/
2 4
/
1
输出: 4

限制:

1 ≤ k ≤ 二叉搜索树元素个数

package LeetCode;

import org.junit.Test;

import javax.swing.tree.TreeNode;
import java.util.ArrayDeque;

public class _15_二叉搜索树的第k大节点 {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    //中序遍历的稍微变形
    public int K=0;
    public int numK=-1;
    public int kthLargest(TreeNode root, int k) {
        if (root==null) return -1;
        K=k;
        order(root);
        return numK;
    }
    public void order(TreeNode root){
        if (root==null)  return;
        order(root.right);
        K--;
        if (K==0){
            numK=root.val;
            return;
        }
        order(root.left);
    }


}

_16_二叉树的深度

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

给定二叉树 [3,9,20,null,null,15,7],

3

/
9 20
/
15 7
返回它的最大深度 3 。

提示:

节点总数 <= 10000

package LeetCode;

import org.junit.Test;

public class _16_二叉树的深度 {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    /*
    采用递归,后序遍历的方法:
    根节点的深度=(左子树的深度,右子树的深度)的最大值+1
    * */
    public int maxDepth(TreeNode root) {
        if (root==null) return 0;
        int left=maxDepth(root.left);
        int right=maxDepth(root.right);
        int max= Math.max(left, right)+1;
        return max;
    }

}

_17_平衡二叉树

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

3

/
9 20
/
15 7
返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

   1
  / \\
 2   2
/ \\

3 3
/
4 4
返回 false 。

限制:

0 <= 树的结点个数 <= 10000

package LeetCode;

import org.junit.Test;

public class _17_平衡二叉树 {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    //判断一颗树是否为平衡二叉树
    public boolean isBalanced(    TreeNode root){
        if (root==null) return true;//空的时候为平衡
        int[] dept

以上是关于2021-6-4笔记01的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

ReactJs学习笔记01

19 01 11 javascript ?????????????????????(???????????????) ??????????????????????????????(代码片段

[linux][c/c++]代码片段01

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

sh bash片段 - 这些片段大多只是我自己的笔记;我找到了一些,有些我已经找到了