美文网首页
【D36】序列化二叉树&字符串的排列&数组中出现次数超过一半的数

【D36】序列化二叉树&字符串的排列&数组中出现次数超过一半的数

作者: sirenyunpan | 来源:发表于2021-03-17 21:16 被阅读0次

    剑指 Offer 37. 序列化二叉树

    请实现两个函数,分别用来序列化和反序列化二叉树。

    • 层序遍历
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Codec {
    
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            if(root == null){
                return "[]";
            }
           
           //1.得到层序遍历列表
            List<String> nodeList = new ArrayList<>();
            Deque<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while(!queue.isEmpty()){
                TreeNode node = queue.poll();
                if(node != null){
                    nodeList.add(String.valueOf(node.val));
                    queue.offer(node.left);
                    queue.offer(node.right);
                }else{
                    nodeList.add("null");
                }
            }
    
            //2.去掉最末尾的null
            int right = nodeList.size() - 1;
            while(right > 0){
                if(!"null".equals(nodeList.get(right))){
                    break;
                }
                right--;
            }
            //3.拼接结果字符串
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            for(int i = 0; i <= right; i++){
                if(i != 0){
                    sb.append(",");
                }
                sb.append(nodeList.get(i));
            }
            sb.append("]");
            return sb.toString();
        }
    
        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
            String[] nodeValues = data.substring(1, data.length() - 1).split(",");
            int len = nodeValues.length;
            //System.out.println(len);
            if(len == 0 || data.equals("[]")){
                return null;
            }
            
            TreeNode root = new TreeNode(Integer.valueOf(nodeValues[0]));
            Queue<TreeNode> nodes = new LinkedList<>();
            //根节点入队
            nodes.offer(root);
            int i = 1;
            
            while(!nodes.isEmpty() && i < len){
                TreeNode temp = nodes.poll();
                if(!nodeValues[i].equals("null")){
                    temp.left = new TreeNode(Integer.valueOf(nodeValues[i]));
                    nodes.offer(temp.left);
                }
                i++;
                if(i < len && !nodeValues[i].equals("null")){
                    temp.right = new TreeNode(Integer.valueOf(nodeValues[i]));
                    nodes.offer(temp.right);
                }
                i++;
            }
            return root; 
        }
    }
    
    // Your Codec object will be instantiated and called as such:
    // Codec codec = new Codec();
    // codec.deserialize(codec.serialize(root));
    

    剑指 Offer 38. 字符串的排列

    输入一个字符串,打印出该字符串中字符的所有排列。
    你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

    • 典型的全排列问题,采用回溯法;哈希表去重
    class Solution {
        HashSet<String> res = new HashSet<>();
        char[] chars;
        int[] visited;
        public String[] permutation(String s) {
            chars = s.toCharArray();
            Arrays.sort(chars);
            visited = new int[chars.length];
    
            List<Character> track = new ArrayList<>();
            dfs(track);
            
            String[] resStr = new String[res.size()];
            int i = 0;
            for(String str : res){
                resStr[i++] = str;
            }
            return resStr;
        }
    
        public void dfs(List<Character> track) {
            if(track.size() == chars.length){
                String s = list2Str(track);
                if(!res.contains(s)){
                    res.add(s);
                }
                return;
            }
    
            for(int i = 0; i < chars.length; i++){
                if(visited[i] == 1){
                    continue;
                }
    
                track.add(chars[i]);
                visited[i] = 1;
    
                dfs(track);
    
                track.remove(track.size() - 1);
                visited[i] = 0;
            }
        }
    
        public String list2Str(List<Character> track){
            StringBuilder sb = new StringBuilder();
            for(Character c : track){
                sb.append(c);
            }
            return sb.toString();
        }
    }
    

    剑指 Offer 39. 数组中出现次数超过一半的数字

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
    你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    • 排序后返回最中间的元素
    class Solution {
        public int majorityElement(int[] nums) {
            int len = nums.length;
            Arrays.sort(nums);
            return nums[len/2];
        }
    }
    

    剑指 Offer 40. 最小的k个数

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    • 调用Array.sort
    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            int[] res = new int[k];
            Arrays.sort(arr);
            for(int i = 0; i < k; i++){
                res[i] = arr[i];
            }
            return res;
        }
    }
    
    • 基于快排
    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            quickSort(arr, 0 , arr.length - 1, k);
            int[] res = new int[k];
            for(int i = 0; i < k; i++){
                res[i] = arr[i];
            }
            return res;
            
        }
    
        public void quickSort(int[] arr, int left , int right,  int k){
            if(left >= right){
                return;
            }
    
            int index = partition(arr, left, right);
            if(left >= k){
                return;
            }
            quickSort(arr, left, index - 1, k);
            quickSort(arr, index + 1, right, k);
        }
    
        public int partition(int[] arr, int left , int right){
            int temp = arr[left];
            while(left < right){
                while(left < right && arr[right] > temp){
                    right--;
                }
                arr[left] = arr[right];
                while(left < right && arr[left] <= temp){
                    left++;
                }
                arr[right] = arr[left];
            }
            arr[left] = temp;
            return left;
        }
    }
    

    相关文章

      网友评论

          本文标题:【D36】序列化二叉树&字符串的排列&数组中出现次数超过一半的数

          本文链接:https://www.haomeiwen.com/subject/gfaecltx.html