(Java版)剑指offer(五)

37.序列化二叉树
这里要保证输出的格式都一致

public class Codec {
    public String serialize(TreeNode root) {
		//使用层序遍历
        if(root == null) return "[]";
        StringBuilder res = new StringBuilder("[");
        Queue<TreeNode> queue = new LinkedList<>() {{ add(root); }};
        while(!queue.isEmpty()) {
            TreeNode node = queue.poll();//先进先出
            if(node != null) {
                res.append(node.val + ",");
                queue.add(node.left);
                queue.add(node.right);
            }
            else res.append("null,");
        }
//       res.deleteCharAt(res.length() - 1);//删除StringBuilder中还未填值的空间,工程习惯,对算法无影响
        res.append("]");
        return res.toString();
    }

    public TreeNode deserialize(String data) {
        if(data.equals("[]")) return null;
        String[] vals = data.substring(1, data.length() - 1).split(","); //substring(1,n-1)是去掉[],vals 是字符数组
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        Queue<TreeNode> queue = new LinkedList<>() {{ add(root); }};
        int i = 1;
        while(!queue.isEmpty()) {
            TreeNode node = queue.poll();
            //左节点
            if(!vals[i].equals("null")) {
                node.left = new TreeNode(Integer.parseInt(vals[i]));//
                queue.add(node.left);
            }
            i++;
            //右节点
            if(!vals[i].equals("null")) {
                node.right = new TreeNode(Integer.parseInt(vals[i]));
                queue.add(node.right);
            }
            i++;
        }
        return root;
    }
}

38,字符串的排列(有难度)

class Solution {
    List<String> res = new LinkedList<>();
    char[] c;
    public String[] permutation(String s) {
        c = s.toCharArray();
        dfs(0);
        return res.toArray(new String[res.size()]);
    }
    void dfs(int x) {
        if(x == c.length - 1) {
            res.add(String.valueOf(c));      // 添加排列方案
            return;
        }
        HashSet<Character> set = new HashSet<>();//为什么每进入一次dfs都要开辟一个set空间。因为set的存储方式不会将原来位置的值覆盖掉。而如果完全相同则是存储失败。
        for(int i = x; i < c.length; i++) {
            if(set.contains(c[i])) continue; // 重复,因此剪枝
            set.add(c[i]);
            swap(i, x);                      // 交换,将 c[i] 固定在第 x 位
            dfs(x + 1);                      // 开启固定第 x + 1 位字符
            swap(i, x);                      // 恢复交换
        }
    }
    void swap(int a, int b) {
        char tmp = c[a];
        c[a] = c[b];
        c[b] = tmp;
    }
}

39 数组中出现次数超过一半的数字

class Solution {
    public int majorityElement(int[] nums) {
        Map<Integer, Integer> counts = new HashMap<>();
        for(int i = 0;i<nums.length;i++){
            int count = counts.getOrDefault(nums[i], 0) + 1;//当有nums[i]时,就是用其对应的value值(初始counts是没有赋值的,所以value都为0,key初始也为0 ,因为Integer型),尾部+1记录出现的次数,最小值为1
            counts.put(nums[i],count);
            if (count > nums.length / 2)
                return nums[i];
        }
        return -1;
    }
}

40,最小的k个数
直接调用排序

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        int[] minarr = new int[k];
        for(int i =0;i<k;i++)
            minarr[i] = arr[i];
        return minarr;
    }
}

41.数据流中的中位数(堆)
构建两个优先级队列(堆)A,B;A小顶堆存放较大的一半,B大顶堆存放较小的一半
添加操作:要保证添加数据之后依然保持中位数特点

class MedianFinder {
    Queue<Integer> A, B;
    public MedianFinder() {
        A = new PriorityQueue<>(); // 小顶堆,保存较大的一半
        B = new PriorityQueue<>(Comparator.reverseOrder()); // 大顶堆,保存较小的一半
    }
	//为什么要有A加入再删除或者B加入再删除动作?是为了在堆中进行排序,加入堆中的元素要按顺序排序
    public void addNum(int num) {
        if(A.size() != B.size()) {
            A.add(num);
            B.add(A.poll());
        } else {
            B.add(num);
            A.add(B.poll());
        }
    }
    public double findMedian() {
        return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;
    }
}

42.连续子数组的最大和
动态规划
当dp[i−1]>0 时:执行 dp[i] = dp[i-1] + nums[i];
当 dp[i−1]≤0 时:执行 dp[i] = nums[i];

class Solution {
    public int maxSubArray(int[] nums) {
        int res = nums[0];
        for(int i=1;i<nums.length;i++){
            nums[i] += Math.max(nums[i-1],0);
            res = Math.max(res,nums[i]);
        } 
        return res;      
    }
}

还可以用求解
如果此道题还要求输出最大子数组,可以提升为中等难度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值