剑指offer六天刷完(三)

二叉搜索树转为双向链表

时间复杂度ON)
空间复杂度ONpublic class Solution {
    private TreeNode pre,head,firstNode;
    public TreeNode Convert(TreeNode pRootOfTree) {
        dfs(pRootOfTree);
        return firstNode;
    }
    public void dfs(TreeNode root){
        if(root==null){
            return;
        }
        dfs(root.left);
        if(head==null){
           head = root;
           firstNode = root;
        }else{
            head = root;
            pre.right = head;
            head.left = pre;
            
        }
        pre = head;
        dfs(root.right);
    }
}

二叉搜索树的后序遍历序列(再做!)

时间复杂度ON)
空间复杂度ONimport java.util.*;
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence==null||sequence.length==0){
            return false;
        }
        int root = Integer.MAX_VALUE;
        Stack<Integer> stack = new Stack<>();
        for(int i=sequence.length-1;i>=0;i--){
            if(sequence[i]>root){
                return false;
            }
            while(!stack.isEmpty()&&stack.peek()>sequence[i]){
                root = stack.pop();
            }
            stack.add(sequence[i]);
        }
        return true;
    }
}

二叉树中和为某一值的路径

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    //res 不要忘记初始化 ,傻X!!!
    private ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        ArrayList<Integer> level = new ArrayList<>();
        int sum = 0;
        dfs(root,target,level,sum);
        return res;
    }
   
    public void dfs(TreeNode root,int target,ArrayList<Integer> level,int sum){
        if(root==null){
            return;
        }
        //这句话要靠前
         level.add(root.val);
        sum = sum+root.val;
        //叶子节点的判断要注意
       
        if(root.left==null&&root.right==null&&sum==target){
            //vel.add(root.val);
            res.add(new ArrayList(level));
            //这句移动要注意
            level.remove(level.size()-1);
            return;
        }
        
        dfs(root.left,target,level,sum);
        dfs(root.right,target,level,sum);
        level.remove(level.size()-1);
        //sum传值调用不用回溯,不过改不改不影响结果,因为每次都是复制了一份新的拷贝
        //sum = sum - root.val;
        return;
    }
}

复杂链表的复制

空间复杂度 O1)
时间复杂度 O(n)
public class Solution {
    public RandomListNode Clone(RandomListNode pHead) {
        if(pHead==null){
            return null;
        }
        RandomListNode dummyNode = new RandomListNode(0);
        //三个步骤只有最后一步是phead.next!=null  前边都是pHead!=null
        dummyNode.next = pHead;
        //扩展列表
        while(pHead!=null){
            RandomListNode temp = new RandomListNode(pHead.label);
            temp.next = pHead.next;
            pHead.next = temp;
            pHead = pHead.next.next;
        }
        //复制random指针
        pHead = dummyNode.next;
        while(pHead!=null){
            ///记住这句话要判断random是否为空,否则会有空指针异常!
            if(pHead.random!=null){
                pHead.next.random = pHead.random.next;
            }
            
            pHead = pHead.next.next;
        }
        //拆分链表
        RandomListNode copy = dummyNode.next.next;
        pHead = dummyNode.next;
        RandomListNode res = dummyNode.next.next;
        while(copy.next!=null){
            pHead.next = pHead.next.next;
            copy.next = copy.next.next;
            copy = copy.next;
            pHead = pHead.next;
        }
        //不要忘记置空
        pHead.next=null;
        return res;
    }
}

字符串的排列

时间复杂度 O(N!N)N 为字符串 s 的长度;时间复杂度和字符串排列的方案数成线性关系,方案数为 N!,即复杂度为 O(N!) ;字符串拼接操作 join() 使用 O(N) ;因此总体时间复杂度为 O(N!N) 。
空间复杂度 O(N^2): 全排列的递归深度为 N ,系统累计使用栈空间大小为 O(N) ;递归中辅助 Set 累计存储的字符数量最多为 N + (N-1) + ... + 2 + 1 =(N+1)N/2 ,即占用 O(N^2)的额外空间。
代码:
import java.util.ArrayList;
import java.util.*;
import java.util.Arrays;
public class Solution {
    //防止重复要用Set
    private Set<String> res = new HashSet<>();
    public ArrayList<String> Permutation(String str) {
       boolean[] visited = new boolean[str.length()];
       
       char[] chars = str.toCharArray();
        dfs(chars,visited,"");
        ArrayList<String> res1 = new ArrayList(res);
        //对String的list排序要用Collections ArrayList只能对int排序
        Collections.sort(res1);
        return res1;
    }
    
    public void dfs(char[] chars,boolean[] visited,String path){
        //这个判断条件要记住
        if(path.length()==chars.length){
            res.add(path);
            return;
        }
        
        for(int i=0;i<chars.length;i++){
            if(visited[i]==true){
                continue;
            }
            visited[i] = true;
            //String 这里要直接传参,不能把path = path+chars[i]写在外边,否则还需要还原现场
            dfs(chars,visited,path+chars[i]);
            visited[i] = false;
        }
        return;
    }
}

找到出现次数大于一半的数字

时间复杂度ON)
空间复杂度O1public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        int n = array.length;
        int res = 0;
        int vote = 0;
        
        for(int num : array){
            if(vote == 0) res = num;
            vote += num == res ? 1 : -1;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值