LeetCode做题笔记

LeetCode 做题笔记

  • 记录算法题过程中遇到的算法
    • leet-1-动态规划解决Fibonacci数列
    • leet-2-摩尔投票法解决众数问题
    • leet-3-厄拉多塞筛法求质数
    • leet-数据结构-1-队列广度优先搜索
    • leet-数据结构-2-栈的实现
    • leet-数据结构-3-循环队列的实现
    • leet-数据结构-4-深度优先搜索
    • leet-数据结构-5-最小栈的实现
    • leet-数据结构-6-有效的括号
    • leet-数据结构-7-逆波兰表达式
    • leet-数据结构-8-二叉树的遍历

记录算法题过程中遇到的算法

记录在做题过程中遇到的较为高效和独特的算法,只是披着leetcode的名字不一定全是leetcode,本帖作为笔记,仅供自己参考,但是开放给所有人。

leet-1-动态规划解决Fibonacci数列

public static int fib(int n) { 
// 计算Fibonacci数列的第n项(动态规划版):O(n)
        if(n < 2) return n;
        int a = 0;//第一个值
        int b = 1;//第二个值
        int tmp = 0;//辅助变量
        for(int i = 2;i <= n;i++){
            tmp = a + b;
            a = b;
            b = tmp;
        }
        return tmp;     
    }

leet-2-摩尔投票法解决众数问题

class Solution {
    public int majorityElement(int[] nums) {
        int result=0;//当前判断的元素
        int count=0;//计算当前的数字出现的次数
        int len=nums.length;
        for(int i=0;i<len;i++){
            if(count==0){//当次数为0时,则换下一判断元素
                result=nums[i];
                count++;
            }else{
                if(nums[i]==result){
                    count++;//当前元素等于判断元素,次数加一
                }else{
                    count--;//不等于则次数减一
                }
            }
        }
        return result;
    }
}

leet-3-厄拉多塞筛法求质数


leet-数据结构-1-队列广度优先搜索

代码模板

/**
 * Return the length of the shortest path between root and target node.
 */
int BFS(Node root, Node target) {
    Queue<Node> queue;  // store all nodes which are waiting to be processed
    int step = 0;       // number of steps neeeded from root to current node
    // initialize
    add root to queue;
    // BFS
    while (queue is not empty) {
        step = step + 1;
        // iterate the nodes which are already in the queue
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                add next to queue;
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}

leet-数据结构-2-栈的实现

// "static void main" must be defined in a public class.
class MyStack {
    private List<Integer> data;               // store elements
    public MyStack() {
        data = new ArrayList<>();
    }
    /** Insert an element into the stack. */
    public void push(int x) {
        data.add(x);
    }
    /** Checks whether the queue is empty or not. */
    public boolean isEmpty() {
        return data.isEmpty();
    }
    /** Get the top item from the queue. */
    public int top() {
        return data.get(data.size() - 1);
    }
    /** Delete an element from the queue. Return true if the operation is successful. */
    public boolean pop() {
        if (isEmpty()) {
            return false;
        }
        data.remove(data.size() - 1);
        return true;
    }
};

public class Main {
    public static void main(String[] args) {
        MyStack s = new MyStack();
        s.push(1);
        s.push(2);
        s.push(3);
        for (int i = 0; i < 4; ++i) {
            if (!s.isEmpty()) {
                System.out.println(s.top());
            }
            System.out.println(s.pop());
        }
    }
}

leet-数据结构-3-循环队列的实现

class MyCircularQueue {
    
    private int[] data;
    private int head;
    private int tail;
    private int size;

    /** Initialize your data structure here. Set the size of the queue to be k. */
    public MyCircularQueue(int k) {
        data = new int[k];
        head = -1;
        tail = -1;
        size = k;
    }
    
    /** Insert an element into the circular queue. Return true if the operation is successful. */
    public boolean enQueue(int value) {
        if (isFull() == true) {
            return false;
        }
        if (isEmpty() == true) {
            head = 0;
        }
        tail = (tail + 1) % size;
        data[tail] = value;
        return true;
    }
    
    /** Delete an element from the circular queue. Return true if the operation is successful. */
    public boolean deQueue() {
        if (isEmpty() == true) {
            return false;
        }
        if (head == tail) {
            head = -1;
            tail = -1;
            return true;
        }
        head = (head + 1) % size;
        return true;
    }
    
    /** Get the front item from the queue. */
    public int Front() {
        if (isEmpty() == true) {
            return -1;
        }
        return data[head];
    }
    
    /** Get the last item from the queue. */
    public int Rear() {
        if (isEmpty() == true) {
            return -1;
        }
        return data[tail];
    }
    
    /** Checks whether the circular queue is empty or not. */
    public boolean isEmpty() {
        return head == -1;
    }
    
    /** Checks whether the circular queue is full or not. */
    public boolean isFull() {
        return ((tail + 1) % size) == head;
    }
}

leet-数据结构-4-深度优先搜索

递归调用栈

boolean DFS(Node cur, Node target, Set<Node> visited) {
    return true if cur is target;
    for (next : each neighbor of cur) {
        if (next is not in visited) {
            add next to visted;
            return true if DFS(next, target, visited) == true;
        }
    }
    return false;
}

显示使用栈

/*
 * Return true if there is a path from cur to target.
 */
boolean DFS(int root, int target) {
    Set<Node> visited;
    Stack<Node> s;
    add root to s;
    while (s is not empty) {
        Node cur = the top element in s;
        return true if cur is target;
        for (Node next : the neighbors of cur) {
            if (next is not in visited) {
                add next to s;
                add next to visited;
            }
        }
        remove cur from s;
    }
    return false;
}

leet-数据结构-5-最小栈的实现

每次入栈存储需要入栈的元素然后再将当前最小元素压入栈中
利用空间 换时间

class MinStack{
	public MinStack() {
    Stack<Integer> stack = new Stack<>();
    }
    public void push(int x) {
        if(stack.isEmpty()){
            stack.push(x);
            stack.push(x);
        }else{
        //将当前元素和当前最小元素压入栈
            int tmp = stack.peek();
            stack.push(x);
            if(tmp<x){
                stack.push(tmp);
            }else{
                stack.push(x);
            }
        }
    }
    public void pop() {
    	//删除元素时需要同时删除栈中的两个元素
        stack.pop();
        stack.pop();
    }
    public int top() {
    	//栈顶元素为栈的倒数第二个元素 倒数第一个元素为当前最小元素
        return stack.get(stack.size()-2);
    }
    public int getMin() {
        return stack.peek();
    }
}

leet-数据结构-6-有效的括号

这道题我在曾经在拼多多的笔试题中遇到过,我并不会做,没有想到要用特殊的数据结构去存储

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

复制别人的代码 思路和我一样代码写的比我的要好很多

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        char[] chars = s.toCharArray();
        for (char aChar : chars) {
            if (stack.size() == 0) {
                stack.push(aChar);
            } else if (isSym(stack.peek(), aChar)) {
                stack.pop();
            } else {
                stack.push(aChar);
            }
        }
        return stack.size() == 0;
    }
    //如果下一个字符和栈顶的字符相匹配就可以出栈一个字符
    private boolean isSym(char c1, char c2) {
        return (c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}');
    }
}

leet-数据结构-7-逆波兰表达式

逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)
逆波兰表达式其实也是计算机执行计算常用的方法,遇到数字入栈,遇到符号出栈两次,计算,结果入栈,重复执行,最后取栈顶元素即为结果

	public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<Integer>();
        for (String token : tokens) {
            if (!token.equals("+")
                    && !token.equals("-")
                    && !token.equals("*")
                    && !token.equals("/")) {
                stack.push(Integer.parseInt(token));
            } else {
                int e2 = stack.pop();
                int e1 = stack.pop();
                stack.push(calculate(e1, e2, token));//计算两次出栈数字的运算结果 除需要判断分母是否为零
            }
        }
        return stack.pop();
    }

leet-数据结构-8-二叉树的遍历

前序遍历:前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树
中序遍历:中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树
后序遍历:后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点
以前序遍历代码为例:

//递归
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> resultList = new ArrayList<>();
        if(root == null){
            return resultList;
        }
        helper(resultList,root);
        return resultList;
    }
    public void helper(List<Integer> resultList,TreeNode root){
        if(root==null)
            return;
        //后序遍历,中序遍历只需要调整这三个的位置
        resultList.add(root.val);
        helper(resultList,root.left);
        helper(resultList,root.right);   
    }
}
//迭代
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            res.add(Integer.valueOf(node.val));
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return res;
    }
}

你可能感兴趣的:(学习记录)