算法题笔记
Q11 翻转链表
本题可通过双指针进行解决,对原始链表中的节点一个一个翻转,最后返回最后一个翻转的节点即可。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
/**
* 翻转链表
* @param head
* @return
*/
public ListNode ReverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
while (cur != null) {
ListNode nxt = cur.next;
cur.next = prev;
if (nxt == null) {
return cur;
}else {
prev = cur;
cur = nxt;
}
}
return null;
}
}
Q12 二叉树所有根节点到叶子结点路径值为Tar的路径
典型的二叉树🌲递归问题,直接借助dfs即可解决。方法
dfs带有当前路径上的值,以及当前路径权值。
首先判断当前节点是不是leaf node。如果是叶子节点的话,进一步判断当前路径和是否与Tar相等,相等的话加入结果集中。树空间所有路径走完即可得到最后结果,具体代码如下
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param sum int整型
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
// write code here
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
ArrayList<Integer> now = new ArrayList<>();
dfs(root,now,res,0,sum);
return res;
}
private void dfs(TreeNode p,ArrayList<Integer> now,
ArrayList<ArrayList<Integer>> res,
int val,int tar) {
if (p == null) {
return;
}
if (p.left == null && p.right == null) {
// leaf node
if (val+p.val == tar) {
now.add(p.val);
res.add(new ArrayList<>(now));
now.remove(now.size()-1);
}
return;
}
// not leaf node
now.add(p.val);
dfs(p.left,now,res,val+p.val,tar);
dfs(p.right,now,res,val+p.val,tar);
now.remove(now.size()-1);
}
}
Q13 两个栈模拟一个队列
十分典型的算法题,在面试pdd、网易的时候都问到了。
算法较为简单。主要思想是,stack1用来填充数据,每次新数据都压入stack1中。stack2用来帮助stack1进行弹出数据过程的过渡,步骤就是先把stack1中除了栈底元素外的所有元素压入stack2中,然后把栈底作为res弹出来,然后把stack2中元素远路弹回stack1中即可,返回res。
具体代码如下:
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack1.isEmpty()) {
return -1;
}
while(stack1.size() > 1) {
stack2.add(stack1.pop());
}
int res = stack1.pop();
while(!stack2.isEmpty()) {
stack1.add(stack2.pop());
}
return res;
}
}
Q14 字符串排列
因为要考虑最后的输出是按照顺序的,但是数据量大的时候最后再排序容易
TLE。我们只需要dfs的时候保证先dfs小的字母即可保证最后输出的字符串一定是从小到大的。最后注意去重即可,具体代码如下。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Solution {
Set<String> seen = new HashSet<>();
public ArrayList<String> Permutation(String str) {
ArrayList<String> res = new ArrayList<>();
char[] c = str.toCharArray();
Arrays.sort(c);
int len = c.length;
int[] memo = new int[len];
dfs(res,c,memo,new char[len],0);
return res;
}
private void dfs(ArrayList<String> res,char[] strArr,
int[] memo,char[] now,
int len) {
if (len == memo.length) {
String r = String.valueOf(now);
if (!seen.contains(r)) {
res.add(r);
seen.add(r);
}
return;
}
for (int i=0;i<memo.length;i++) {
if (memo[i] == 0) {
now[len] = strArr[i];
memo[i] = 1;
dfs(res,strArr,memo,now,len+1);
memo[i] = 0;
}
}
}
}
Q5 数组第K大的数
本题为LeetCode上经典算法题,面试常问的算法。有许多解法,面试中较为常考的一般是快速选择方法,还可以使用堆等方法~
快速选择法的核心思想同快速排序一样~
下面参考文章讲了很多不同方法,值得学习:
import java.util.*;
public class Solution {
public int findKth(int[] a, int n, int K) {
// write code here
// 1 big => n small => n-1 idx
// 2 big => n-1 small =>. n-2 idx
// K big => n+1-K small => n-K idx
quickPick(a,0,n-1,n-K);
return a[n-K];
}
private void quickPick(int[] arr,int l,int r,int k) {
int lcur = l;
int rcur = r;
int pivot = arr[l];
while (lcur < rcur) {
while (lcur < rcur && arr[rcur]>=pivot) rcur--;
while (lcur < rcur && arr[lcur]<=pivot) lcur++;
if (lcur < rcur) {
int temp = arr[lcur];
arr[lcur] = arr[rcur];
arr[rcur] = temp;
}
}
arr[l] = arr[lcur];
arr[lcur] = pivot;
if (lcur == k) {
return;
}else if (lcur < k) {
quickPick(arr,lcur+1,r,k);
}else {
// lcur > k
quickPick(arr,l,lcur-1,k);
}
}
}
Q6 买卖股票的最好时机
股票问题是LeetCode上的一个经典动态规划类型问题。
本题是股票问题的一个最简单问题,用户只可以交易一次。只需判断当前价格之前最低的价格是多少,然后判断是否比max变量记录的值要大即可,初始化max=0;
具体代码如下:
import java.util.*;
public class Solution {
/**
*
* @param prices int整型一维数组
* @return int整型
*/
public int maxProfit (int[] prices) {
// write code here
if (prices.length <= 1){
return 0;
}
int res = 0;
int prev = prices[0];
for (int i=1;i<prices.length;i++) {
res = Math.max(res,prices[i]-prev);
prev = Math.min(prev,prices[i]);
}
return res;
}
}
Q7 旋转数组查找某值
经典题,具体代码如下
import java.util.*;
public class Solution {
/**
*
* @param A int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] A, int target) {
// write code here
int len = A.length;
return helper(A,0,len-1,target);
}
private int helper(int[] arr,int l,int r,int tar) {
if(l > r) return -1;
if (l == r) {
return arr[l] == tar ? l:-1;
}
int mid = (l+r)>>1;
if (arr[mid] == tar) {
return mid;
}else{
int lp = helper(arr,mid+1,r,tar);
int rp = helper(arr,l,mid-1,tar);
return lp == -1 ? rp:lp;
}
}
}
Q8 Fibonacci数列
经典斐波那契数列问题,可用
dfs或者dp
具体代码如下:
public int Fibonacci(int n) {
if (n<=1) return n;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for (int i=2;i<=n;i++) {
dp[i] = dp[i-1]+dp[i-2];
}
return dp[n];
}
```