记录在做题过程中遇到的较为高效和独特的算法,只是披着leetcode的名字不一定全是leetcode,本帖作为笔记,仅供自己参考,但是开放给所有人。
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;
}
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;
}
}
代码模板
/**
* 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
}
// "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());
}
}
}
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;
}
}
递归调用栈
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;
}
每次入栈存储需要入栈的元素然后再将当前最小元素压入栈中
利用空间 换时间
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();
}
}
这道题我在曾经在拼多多的笔试题中遇到过,我并不会做,没有想到要用特殊的数据结构去存储
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
复制别人的代码 思路和我一样代码写的比我的要好很多
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 == '}');
}
}
逆波兰式(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();
}
前序遍历:前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树
中序遍历:中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树
后序遍历:后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点
以前序遍历代码为例:
//递归
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;
}
}