記一些常見的手撕演算法
阿新 • • 發佈:2019-01-09
怕什麼真理無窮,進一寸有進一寸的歡喜
1.二分查詢
public int binarySearch(int[] arr,int key){ int low = 0; int high = arr.length - 1; int mid = 0; if(key>arr[high]||key<arr[low]||low>high){ return -1; } while(low<=high){ mid = (low + high)/2; if(arr[mid] > key){ high = mid - 1; }else if(arr[mid] < key){ low = mid +1; }else { return mid; } } return -1; }
2.快速排序
public void quickSort(int[] arr,int low,int high){ int start = low; int end = high; int key = arr[low]; while(start < end){ //從後向前找 while(start < end && arr[end] >= key){ end--; } //交換arr-end和arr-start if(arr[end] >= key){ int temp = arr[end]; arr[end] = arr[start]; arr[start] = temp; } //從前向後找 while(start < end && arr[start] <= key){ start++; } //交換 if(arr[start] >= key){ int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } } //遞迴 if(start > low){ quickSort(arr,low,start-1); } if(end < high){ quickSort(arr,end+1,high); } }
3.二叉樹的層次遍歷
public void LaywerTraversal(TreeNode root){ if(root==null){ return; } LinkedList<TreeNode> list = new LinkedList<TreeNode>(); list.add(root); TreeNode temp; while (!list.isEmpty()){ temp = list.poll(); System.out.println(temp.val); if(temp.left != null){ list.add(temp.left); } if(temp.right!=null){ list.add(temp.right); } } }
4.蛇形列印二叉樹
public void snakePrint(TreeNode root){
if(root == null){
return;
}
//用2個棧解決
LinkedList<TreeNode> list1 = new LinkedList<TreeNode>();
LinkedList<TreeNode> list2 = new LinkedList<TreeNode>();
TreeNode curNode;
int flag =0;
list1.add(root);
while(!list1.isEmpty()){
curNode = list1.remove(list1.size() - 1);
System.out.println(curNode.val);
if(flag ==0){
if(curNode.left != null){
list2.add(curNode.left);
}
if(curNode.right != null){
list2.add(curNode.right);
}
}else {
if(curNode.right != null){
list2.add(curNode.right);
}
if(curNode.left != null){
list2.add(curNode.left);
}
}
//列印下一層
if(list1.isEmpty()){
flag = 1 - flag;
ListNode<TreeNode> temp;
temp = list1;
list1 = list2;
list2 = temp;
}
}
}
5.連結串列實現加法(逆序連結串列)
public linkNode linkedAdd(linkNode link1, linkNode link2){
if(link1 == null || link2 == null){
return (link1 ==null)?link2:link1;
}
//所返回的頭節點
linkNode res;
linkNode Ptail = res;
linkNode p1 = link1,p2 = link2;
//進位符
int carry = 0;
int temp;
//處理長度相同的部分
while(p1!=null &&p2!=null){
temp = p1.val + p2.val +carry;
carry = temp/10;
temp = temp%10;
LinkNode cur = new LinkNode(temp);
Ptail.next = cur;
Ptail = cur;
p1 = p1.next;
p2 = p2.next;
}
//處理2個連結串列中較長的部分
linkNode p = (p1!=null)?p1:p2;
while(p!=null){
temp = p.val + carry;
carry = temp/10;
temp = temp%10;
LinkNode cur = new LinkNode(temp);
Ptail.next = cur;
Ptail = cur;
p = p.next;
}
//處理可能存在的進位
if(carry!=0){
LinkNode cur = new LinkNode(carry);
Ptail.next = cur;
}
return sum;
}
6.反轉連結串列
public listNode reverse(listNode head){
if(head ==null){
return null;
}
if(head.next ==null){
return head;
}
//res為返回連結串列的頭指標
//p為當前指標 pre為前指標
listNode res = null;
listNode p = head;
listNode pre = null;
while(p!=null){
listNode temp = p.next;
if(temp == null){
res = p;
}
p.next = pre;
pre = p;
p = temp;
}
return res;
}
7.查詢陣列中第k大的數
public int find(int[] arr,int k,int low,int high){
//處理特殊情況
int len = arr.length;
if(k>len){
return -1;
}
//降序排列,快排後陣列被切分為兩個
int index =0;
int cutPoint = partition(arr,low,high);
if(cutPoint == k - 1){
index = cutPoint;
return arr[index];
}else if(cutPoint >= k - 1){
return arr[topK(arr,low,cutPoint - 1)];
}else {
return arr[topK(arr,cutPoint + 1,high)];
}
}
public int partition(int[] arr.int low,int high){
int key = arr[low];
while(low<high){
while(arr[high]<=key&&low<high){
high--;
}
arr[low] = arr[high];
while(arr[low]>=key&&low<high){
low++;
}
arr[high] = arr[low];
}
arr[high] = key;
return high;
}
8.求一個數字的平方根
public double sqrt(double target,double prescise){
double start = 0;
double end = target;
double middle,square;
if(target < 0){
return -1.0;
}
if(target >=1.0){
while(start - end > prescise){
middle = (start + end)/2;
square = middle*middle;
if(square > target){
end = middle;
}else{
start = middle;
}
}
return (start + end)/2;
}else {
start = target;
end = 1;
while(end - start > prescise){
middle = (start + end)/2;
square = middle*middle;
if(square > target){
end = middle;
}else {
start = middle;
}
}
return (start + end)/2;
}
}
9.連續子陣列最大和
public int getSubString(int[] arr){
if(arr.length == 0){
return -1;
}
int max = arr[0];
int cur = arr[0];
for(int i =1;i<arr.length;i++){
cur = cur > 0?cur + arr[i]:arr[i];
if(cur > max){
max = cur;
}
}
return max;
}
10.股票的最大利潤(一次交易)
public int maxProfit(int[] arr){
if(arr.length==0||arr==null){
return -1;
}
int buy = arr[0];
int max = 0;
for(int i =0;i<arr.length;i++){
if(arr[i]<buy){
buy = arr[i];
}else {
int profits = arr[i] - buy;
if(max < profits){
max = profits;
}
}
}
return max;
}
11.二叉樹的深度
public int depthOfTree(TreeNode root){
//認為空樹的深度為0
if(root==null){
return 0;
}
int leftDepth = depthOfTree(root.left);
int rightDepth = depthOfTree(root.right);
return math.max(leftDepth,rightDepth) + 1;
}
12.二叉樹的最小深度
public int minDepthOfTree(TreeNode root){
if(root==null){
return 0;
}
int minLeft = minDepthOfTree(root.left);
int minRight = minDepthOfTree(root.right);
if(minLeft==0||minRight==0){
return minLeft+minRight+1;
}else{
return math.min(minLeft,minRight) +1;
}
}
13.二叉樹的先序遍歷
public void preOrder(TreeNode root){
//先序遍歷需要用一個棧
Stack<TreeNode> sk = new Stack();
while(root!=null || !sk.isEmpty()){
while(root!=null){
System.out.print(root.value);
sk.push(root);
root = root.left;
}
if(!sk.isEmpty()){
root = sk.pop().right;
}
}
}
14.二叉樹的中序遍歷
public void midOrder(TreeNode root){
Stack<TreeNode> sk = new Stack<TreeNode>();
while(root!=null || !sk.isEmpty()){
while(root!=null){
sk.push(root);
root = root.left;
}
if(!sk.isEmpty()){
root = sk.pop();
System.out.print(root.value);
root = root.right;
}
}
}
15.二叉樹的後序遍歷
public void postOrder(TreeNode root){
Stack<TreeNode> sk1 = new Stack<TreeNode>();
Stack<Integer> sk2 = new Stack<>();
while(root!=null || !sk1.isEmpty()){
while(root!=null){
sk1.push(root);
sk2.push(0);
root = root.left;
}
while(!sk1.isEmpty() &&sk2.peek() == 1){
sk2.pop();
System.out.println(sk1.pop().value);
}
if(!sk1.isEmpty()){
sk2.pop();
sk2.push(1);
root = sk1.peek();
root = root.right;
}
}
}