最近在準備面試,發現一個不錯的網站推薦給你們。也但願經過Go實現來把裏面 劍指offer算法 的題作一下。
若是以爲幫到了你,但願能爲我點個贊呀。
若是發現代碼有錯,很是但願您可以在留言中指出。
https://github.com/CyC2018/CS...
文章只貼本身寫的代碼,題目的全部內容和解題思路都在上面的網站裏。
一些比較簡單無聊的題,就跳過。。html
這一節不出如今劍指offer裏邊,可是常常面試問到。
1.歸併排序ios
package main import ( "math/rand" "time" ) // 產生n個隨機數 func CreateList(list []int, n int) []int { s1 := rand.NewSource(time.Now().Unix()) r1 := rand.New(s1) for i := 0; i < n; i++ { list = append(list, r1.Intn(100)) } return list } func Merge(list []int, a, b int) { var ( i, j int mid int pos int ) temp := make([]int, len(list)) copy(temp, list) i = a mid = (a + b) / 2 j = mid + 1 pos = a for i <= mid && j <= b { if temp[i] < temp[j] { list[pos] = temp[i] pos++ i++ } else { list[pos] = temp[j] pos++ j++ } } for i <= mid { list[pos] = temp[i] pos++ i++ } for j <= b { list[pos] = temp[j] pos++ j++ } } // 左閉右閉[a,b] func MergeSort(list []int, a, b int) { if a+1 >= b { if list[a] > list[b] { list[a], list[b] = list[b], list[a] } return } // 排序包括下標(a+b)/2的值 MergeSort(list, a, (a+b)/2) MergeSort(list, (a+b)/2+1, b) Merge(list, a, b) } func main() { // var inputList = []int{5, 3, 8, 22, 76, 1, 31, 55} var inputList = []int{} inputList = CreateList(inputList, 10) MergeSort(inputList, 0, len(inputList)-1) fmt.Println(inputList) }
2.快排c++
// 左閉右閉[a,b] func QuickSort(list []int) { var ( midValue int head, tail int ) if len(list) <= 1 { return } head = 1 midValue = list[0] tail = len(list) - 1 for head < tail { for list[head] < midValue { head++ if head >= tail { goto END } } for list[tail] > midValue { tail-- if head >= tail { goto END } } list[head], list[tail] = list[tail], list[head] head++ tail-- } END: if list[head] > midValue { list[0], list[head-1] = list[head-1], list[0] QuickSort(list[0 : head-1]) QuickSort(list[head:]) } else { list[0], list[head] = list[head], list[0] QuickSort(list[0:head]) QuickSort(list[head+1:]) } }
3.堆排序
推薦文章:
https://www.cnblogs.com/cheng...
https://blog.csdn.net/MoreWin...git
// i爲處理節點,其是從孩子節點向下影響堆。 // n爲堆的節點數 // 其存在一個前提假設,就是兩個孩子都已是大頂堆 func MaxHeapFixDown(list []int, i int, n int) { var ( parent int kid int ) parent = i // (i+1)*2 和 (i+1)*2 -1 :爲孩子節點 kid = (i+1)*2 - 1 for kid < n { // 取孩子最大的一個 if kid+1 < n && list[kid+1] > list[kid] { kid++ } // 最大的孩子和父親比較 if list[parent] < list[kid] { // 若是孩子大,則交換 list[parent], list[kid] = list[kid], list[parent] // 父親,孩子換人 parent = kid kid = (parent+1)*2 - 1 continue } else { // 若是父親大,則退出,主要是假設在兩個子樹原本都是大頂堆 return } } } // 大頂堆生成 func CreateMaxHeap(list []int) { // 從最小的非葉子節點開始生成。 // 這樣就會一直處在 兩個孩子都已是大頂堆 的前提 // n := (len(list) - 1) / 2 for n := (len(list) - 1) / 2; n >= 0; n-- { MaxHeapFixDown(list, n, len(list)) } } // 從小到大排序 func HeapSort(list []int) { //1.大頂堆生成 CreateMaxHeap(list) // 根與最後一個交換,此時咱們概念中的堆的大小將減一 // 也就是少一個節點不在大頂堆的範圍內 for n := len(list) - 1; n > 0; n-- { list[0], list[n] = list[n], list[0] // 由於動了根節點,對根節點進行處理 MaxHeapFixDown(list, 0, n-1) } } func main() { var inputList = []int{5, 3, 8, 22, 76, 1, 31, 55} // var inputList = []int{} // inputList = CreateList(inputList, 10) HeapSort(inputList) fmt.Println(inputList) }
#include <iostream> using namespace std; template <class T> int getArrayLen(T& array){ return sizeof(array)/sizeof(array[0]); } int main(){ int a[6] = {1,4,2,7,3,9}; int seq; int gap,i,j,k; int arrayLen; arrayLen = getArrayLen(a); gap = arrayLen; for(gap = gap/2;gap > 0;gap = gap/2){ for(j = gap;j < arrayLen;j++){ for(k = j; k-gap >= 0 && a[k] < a[k-gap]; k -= gap){ int temp = a[k]; a[k] = a[k-gap]; a[k-gap] = temp; } } } for(i = 0;i < 6;i++){ cout << a[i] << " " << endl; } }
c++版本。。
很好的教程視頻:https://www.bilibili.com/vide...github
#include <iostream> using namespace std; #define MAX_SIZE 1000 int CreateTree(int *a,int *tree,int root,int start,int end){ // cout << "start:" << start << "\t\t" << "end:" << end << endl; if(start == end){ // cout << "tree[rNote] = " << a[start] << endl; tree[root] = a[start]; return tree[root]; } int mid = (start+end)/2; int lc,rc; int lres,rres; lc = root*2+1; rc = root*2+2; lres = CreateTree(a,tree, lc, start,mid); rres = CreateTree(a,tree, rc,mid+1, end); // cout << "lres:" << lres << "\t\t" << "rres:" << rres << endl; tree[root] = lres +rres; return tree[root]; } void Update(int *a,int *tree,int root,int start,int end,int updateNode,int val){ if(start == end){ a[updateNode] = val; tree[start] = val; return; } int mid = (start+end)/2; int lc,rc; lc = root*2 + 1; rc = root*2 + 2; if(updateNode<=mid){ Update(a,tree,lc,start,mid,updateNode,val); }else{ Update(a,tree,rc,mid+1,end,updateNode,val); } tree[root] = tree[lc] + tree[rc]; return; } int query(int *a,int *tree,int root,int start,int end,int left,int right){ int mid = (start + end)/2; int lc,rc; int lres,rres; lc = root*2 + 1; rc = root*2 + 2; cout << "start:" << start << "\t\t" << "end:" << end << endl; if(right < start || left >end ){ return 0; }else if (start == end){ // cout << tree[start] << endl; return a[start]; }else if(left<=start && right>=end){ // cout << tree[start] << endl; return tree[root]; }else{ lres = query(a,tree,lc,start,mid,left,right); rres = query(a,tree,rc,mid+1,end,left,right); // cout << tree[start] << endl; return lres +rres; } } int main(){ int a[6] = {1,4,2,7,3,9}; int tree[MAX_SIZE]; CreateTree(a,tree,0,0,5); cout << "done" <<endl; Update(a,tree,0,0,5,5,1); cout << "done" <<endl; for(int i=0;i < 6;i++){ cout << tree[i] << " "; } cout << "done" <<endl; cout << query(a,tree,0,0,5,2,5); }
推薦文章:
https://zhuanlan.zhihu.com/p/...
https://blog.csdn.net/v_JULY_...
性質面試
3.數組中重複的數字算法
// 數組中重複的數字 func topic3() { // 交換函數 swap := func(list []int, i, j int) { list[i], list[j] = list[j], list[i] } input := []int{2, 3, 1, 0, 2, 5} for i := 0; i < len(input); i++ { // 將轉換後 for i != input[i] { // i要換到input[i]的位置,可是若是input[i]位置的值(intput[input[i]])等與input[i],說明重複來了 if input[i] == input[input[i]] { fmt.Println(input[i], "重複") goto END } swap(input, i, input[i]) } } END: fmt.Println("done") }
4.二維數組中的查找數組
// 我本身最初想到的方法 // 時間消費在算等差值d這個數組(這裏懶得寫),以及下面的關於row的循環 func topic4() { list := [5][5]int{ {1, 4, 7, 11, 15}, {2, 5, 8, 12, 19}, {3, 6, 9, 16, 22}, {10, 13, 14, 17, 24}, {18, 21, 23, 26, 30}, } // 等差值,都爲3只是特殊 d := [5]int{3, 3, 3, 3, 3} // 行列數 col := 5 row := 5 var input int fmt.Scanf("%d", &input) for i := 0; i < row; i++ { if input > list[i][col-1] || input < list[i][0] { // 比該行最大還大或者比最小的還小,下一行 continue } else { if (input-list[i][0])%d[i] == 0 { fmt.Println("true") goto DONE } continue } } fmt.Println("false") DONE: fmt.Println("done") }
7.重建二叉樹app
type treeNode struct { value int left *treeNode right *treeNode } func CreateTree(preorder, inorder []int) (ptNode *treeNode) { var ( leftChiledSize int ) if len(preorder) != len(inorder) { fmt.Println("error") // debug panic("err1") } ptNode = &treeNode{ left: nil, right: nil, value: preorder[0], } // 遞歸退出條件 if len(preorder) == 1 { return ptNode } leftChiledSize = GetLeftChiledSize(preorder[0], inorder) ptNode.left = CreateTree(preorder[1:1+leftChiledSize], inorder[0:leftChiledSize]) ptNode.right = CreateTree(preorder[1+leftChiledSize:], inorder[leftChiledSize+1:]) return ptNode } //獲取左子樹節點數 func GetLeftChiledSize(root int, inorder []int) int { for i := 0; i < len(inorder); i++ { if root == inorder[i] { return i } } // debug panic("err2") } // 後續遍歷 func PostOrderTraversal(ptree *treeNode) { if ptree.left == nil && ptree.right == nil { fmt.Println(ptree.value) return } if ptree.left != nil { PostOrderTraversal(ptree.left) } if ptree.right != nil { PostOrderTraversal(ptree.right) } fmt.Println(ptree.value) } func topic7() { preorder := []int{3, 9, 20, 15, 7} inorder := []int{9, 3, 15, 20, 7} treeRoot := CreateTree(preorder, inorder) PostOrderTraversal(treeRoot) }
8.二叉樹的下一個結點ide
type treeNode struct { value int parent *treeNode left *treeNode right *treeNode } func CreateTree(preorder, inorder []int) (ptNode *treeNode) { var ( leftChiledSize int ) if len(preorder) != len(inorder) { fmt.Println("error") // debug panic("err1") } ptNode = &treeNode{ parent: nil, left: nil, right: nil, value: preorder[0], } // 遞歸退出條件 if len(preorder) == 1 { return ptNode } leftChiledSize = GetLeftChiledSize(preorder[0], inorder) ptNode.left = CreateTree(preorder[1:1+leftChiledSize], inorder[0:leftChiledSize]) ptNode.left.parent = ptNode ptNode.right = CreateTree(preorder[1+leftChiledSize:], inorder[leftChiledSize+1:]) ptNode.right.parent = ptNode return ptNode } func GetLeftChiledSize(root int, inorder []int) int { for i := 0; i < len(inorder); i++ { if root == inorder[i] { return i } } // debug panic("err2") } // 前序遍歷獲取節點 func PreOrderGetNode(ptree *treeNode, target int) (res *treeNode) { if ptree.value == target { return ptree } if ptree.left != nil { if res = PreOrderGetNode(ptree.left, target); res != nil { return res } } if ptree.right != nil { if res = PreOrderGetNode(ptree.right, target); res != nil { return res } } // debug // fmt.Println("can not find") return nil } //獲取中序遍歷下的下一個節點 func InOrderNext(pt *treeNode) (res *treeNode) { // 有右子樹 -> 取右樹最左節點 if pt.right != nil { circle := pt.right for circle.left != nil { circle = circle.left } return circle } // 無右子樹 -> 向上找第一個左連接指向的樹包含該節點的祖先節點。 circle := pt for circle.parent != nil { if circle.parent.left == circle { return circle.parent } circle = circle.parent } // debug fmt.Println("cannot find") return nil } func topic8() { preorder := []int{3, 9, 20, 15, 7} inorder := []int{9, 3, 15, 20, 7} // 生成樹 rootTree := CreateTree(preorder, inorder) // 前序遍歷獲取值爲15的節點 target := PreOrderGetNode(rootTree, 7) res := InOrderNext(target) if res == nil { fmt.Println("沒有下一個節點") } else { fmt.Println(res.value) } }