Leetcode每天五题-07

  1. 二叉树中的最大路径和

给定一个非空二叉树,返回其最大路径和。本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例 1:

输入: [1,2,3]
输出: 6

示例 2:

输入: [-10,9,20,null,null,15,7]
输出: 42

class Solution {
       /**
        对于任意一个节点, 如果最大和路径包含该节点, 那么只可能是两种情况:
        1. 其左右子树中所构成的和路径值较大的那个加上该节点的值后向父节点回溯构成最大路径
        2. 左右子树都在最大路径中, 加上该节点的值构成了最终的最大路径
        **/
    private int res = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        if(root == null){
            return 0;
        }
        getMax(root);
        return res;
    }
    public int getMax(TreeNode root) {
        if(root == null){
            return 0;
        }
        //左子树
        int leftMax = Math.max(0,getMax(root.left));
        //右子树
        int rightMax = Math.max(0,getMax(root.right));
        // 判断在该节点包含左右子树的路径和是否大于当前最大路径和
        res = Math.max(leftMax+rightMax+root.val,res); 
        
        return Math.max(leftMax,rightMax)+root.val;
    }
}
  1. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for(int i=0;i<nums.length;i++){
            ans^=nums[i];
        }
        return ans;   
    }
}
  1. 环形链表

给定一个链表,判断链表中是否有环。

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = null;
        ListNode low = null;
        low = fast = head;
        while(fast != null && fast.next != null){
            low = low.next;
            fast = fast.next.next;
            if(fast == low){
                return true;
            }
        }
        return false;
    }
}
  1. LRU缓存机制

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?

class LRUCache {

	private Map<Integer, Integer> values = new HashMap<>();
	private LinkedList<Integer> list = new LinkedList<>();
	private final int capacity;

	public LRUCache(int capacity) {
		this.capacity = capacity;
	}

	public int get(int key) {
		return values.containsKey(key) ? getValueAndmoveToHead(key) : -1;
	}

	public void put(int key, int value) {
		// 如果是修改则要将其移到首部
		if (values.containsKey(key)) {
			getValueAndmoveToHead(key);
		}
		// 直接移到首部
		else
			list.addFirst(key);
		// 超过容量要删除末尾
		values.put(key, value);
		if (values.size() > capacity) {
			removeLast();
		}
	}

	private void removeLast() {
		values.remove(list.removeLast());
	}

	private int getValueAndmoveToHead(int key) {
		int value = values.get(key);
		list.remove(Integer.valueOf(key));
		list.addFirst(Integer.valueOf(key));
		return value;
	}

}
  1. 最小栈

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) – 将元素 x 推入栈中。
  • pop() – 删除栈顶的元素。
  • top() – 获取栈顶元素。
  • getMin() – 检索栈中的最小元素。

方案一:

class MinStack {
    private Stack<Integer> data;
    private Stack<Integer> min;
    public MinStack() {
        data = new Stack<Integer>();
        min = new Stack<Integer>();
    }
    
    public void push(int x) {
        data.push(x);
        if(min.isEmpty() || x <= min.peek()){
            min.push(x);
        }
    }
    
    public void pop() {
        int e = data.pop();
        if(e == min.peek()){
            min.pop();
        }
    }
    
    public int top() {
        return data.peek();
    }
    
    public int getMin() {
        return min.peek();
    }
}

方案二:

public class MinStack {
	private Stack<Integer> data;
	private Stack<Integer> min;

	public MinStack() {
		data = new Stack<Integer>();
		min = new Stack<Integer>();
	}

	public void push(int x) {
		data.push(x);
		//当栈顶元素更小时重复压入
		if ((min.isEmpty() || x <= min.peek() ? min.push(x) : min.push(min.peek())) == 0);
	}

	public void pop() {
		data.pop();
		min.pop();
	}

	public int top() {
		return data.peek();
	}

	public int getMin() {
		return min.peek();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值