算法刷题日志

文章目录

    • [3729. 改变数组元素](https://www.acwing.com/problem/content/description/3732/)
    • 树的遍历

3729. 改变数组元素

算法刷题日志_第1张图片

开一个数组v(初始化都是零) 每次对数组v(i - ai + 1, i)做差分操作,
对数组v求前缀和 得数组a 如果ai的位置为0,表示它没有操作过,就是0;
如果大于等于1 ,就是1。

import java.util.*;

public class Main{
    static int N = 200010;
    static int n, x;
    static int[] b = new int[N];
    public static void insert(int l, int r, int c){
        b[l] += c;
        b[r + 1] -= c;
    }

    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int T = scan.nextInt();

        while (T -- > 0){
            n = scan.nextInt();
            Arrays.fill(b, 0); // 多组测试数据,每次清空一下差分数组

            for (int i = 1; i <= n; i ++){
                x = scan.nextInt();
                //插入的数不能比i大
                x=Math.min(x,i);
                if (x != 0) insert(i-x+1, i, 1); //将以i为结尾的x个元素都+1,后面元素-1,差分
            }

            for (int i = 1; i <= n; i ++){
                b[i] += b[i - 1];  //求一下差分数组,前缀和
                System.out.print(Math.min(1, b[i]) + " "); //将所有大于1的元素都定于1
            }
            System.out.println();
        }
    }
}



树的遍历

算法刷题日志_第2张图片

总体思路
如何由中序和后序确定一棵二叉树
一棵二叉树可由它的中序遍历(左 中 右)和后序遍历(左 右 中)确定
这是因为:
1.后序遍历的最后一定是该树或子树的根
2.中序遍历根的左右分左子树和右子树
所以可以通过后序遍历找到根的值,然后再到中序序列里找到根的位置再将该树分为左子树与右子树 然后不断递归即可通过中序和后序重塑一棵树
使用 bfs实现层序遍历

import java.util.*;
import java.util.Scanner;
public class Main {
   static  int N = 35;
   static  int []a = new int [N];//存二叉树的中序遍历
   static  int []b = new int [N]; //存二叉树的后序遍历
  static Map<Integer, Integer> pos = new HashMap<>();   //用来存根节点在中序遍历中的位置
    static int[] l = new int[N]; //存该节点的左子树的根
    static int[] r = new int[N];  //存该节点的右子树的根
    
    public  static  int bulid(int al, int ar ,int bl,int br){
        int root = b[br];
        int k =pos.get(root);
        //如果中序遍历区间的左端点比根节点小,说明这个根节点有左子树,继续进行递归
        //判断右子树同理
        //具体区间范围是通过列方程k-1-al=x-bl        解得 x = k-al+bl-1, 至于减一加一是区间移动
        //左子树
        if(al<k) l[root]=bulid(al,k-1,bl,k-al+bl-1);
        //右子树
        if(ar>k) r[root]=bulid(k+1,ar,k-al+bl,br-1);
        return root;
    }
public  static  void bfs(int root) {
        Queue<Integer>  q = new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()) {
            int t = q.poll();
            System.out.print(t +" ");
            if(l[t]!=-1)q.add(l[t]);
            if(r[t]!=-1)q.add(r[t]);
        }

}
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i <n; i++) b[i]=sc.nextInt();
      for (int i = 0; i < n; i ++){
            a[i] = sc.nextInt();
            pos.put(a[i], i);  //存下中序遍历每个节点的位置
        }
        Arrays.fill(l,-1);
        Arrays.fill(r,-1);
      int root =  bulid(0,n-1,0,n-1);
            bfs(root);
        }
    }

你可能感兴趣的:(算法,java,数据结构)