Go 的面试基础算法(一)

  • 两个数组求交集
    • 思路,把两个数组合并成一个数组,然后通过 hash 表找出数组中重复的元素
package main

import "fmt"

func ArrayIntersection(arr []int, arr1 []int) []int {

	var intersection []int
	arr = append(arr, arr1...)
	sameElem := make(map[int]int)

	for _, v := range arr {
		if _, ok := sameElem[v]; ok {
			intersection = append(intersection, v)
		} else {
			sameElem[v] = 1
		}
	}
	return intersection
}

func main() {

	arr1 := []int{1, 2, 3, 4, 5, 6}
	arr2 := []int{5, 6, 7, 8, 9, 0}

	fmt.Println(ArrayIntersection(arr1, arr2))
}


  • 寻找最长含有不重复字符的字串长度大小
package main

import "fmt"

func lengthOfNonRepeatingSubStr(s string) int {
	lastOccurred := make(map[rune]int)
	start := 0
	maxLength := 0
	for i, ch := range []rune(s) {

		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastOccurred[ch] + 1
		}
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}
	return maxLength
}
func main() {
	fmt.Println(lengthOfNonRepeatingSubStr("hello 世界!"))
}


  • 链表反转

type Node struct {
	value int
	next  *Node
}


func reverse(head *Node) *Node {

	var pre *Node = nil
	for head != nil {
		temp := head.next
		head.next = pre
		pre = head
		head = temp
	}
	return pre
}

func printNode(head *Node) {
	for head != nil {
		fmt.Println(head.value)
		head = head.next
	}
}


  • 单链表是否存在环

type Node struct {
	value int
	next  *Node
}

func hasCycle(head *Node) bool {
	fast := head
	slow := head
	for fast != nil && fast.next != nil {
		slow = slow.next
		fast = fast.next.next
		if fast == slow {
			return true
		}
	}
	return false
}


  • 大整数加法
func stringReverse(str string) string {
	reverse := []rune(str)
	strLen := len(str)
	for i, j := 0, strLen-1; i < j; i, j = i+1, j-1 {
		reverse[i], reverse[j] = reverse[j], reverse[i]
	}
	return string(reverse)
}

func add(str1 string, str2 string) string {

	if len(str1) < len(str2) {
		str1 = strings.Repeat("0", len(str2)-len(str1)) + str1
	} else if len(str1) > len(str2) {
		str2 = strings.Repeat("0", len(str1)-len(str2)) + str2
	}
	str1 = stringReverse(str1)
	str2 = stringReverse(str2)

	count := len(str1)
	nums := make([]byte, count)
	carry := false

	for i := 0; i < count; i++ {
		sum := str1[i] - '0' + str2[i] - '0'
		if carry {
			sum++
		}
		if sum > 9 {
			sum = sum - 10
			carry = true
		} else {
			carry = false
		}
		nums[i] = sum + '0'
	}

	result := stringReverse(string(nums))
	if carry {
		result = "1" + result
	}
	return result

}


  • 大整数乘法

func Reverse(s string) string {
	r := []rune(s)
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return string(r)
}

func LargeNumberMultiplication(a string, b string) (result string) {

	a = Reverse(a)
	b = Reverse(b)
	c := make([]byte, len(a)+len(b))

	for i := 0; i < len(a); i++ {
		for j := 0; j < len(b); j++ {
			c[i+j] += (a[i] - '0') * (b[j] - '0')
		}
	}

	var plus byte = 0

	for i := 0; i < len(c); i++ {
		if c[i] == 0 {
			break
		}
		temp := c[i] + plus
		plus = 0
		if temp > 9 {
			plus = temp / 10
			result += string(temp - plus*10 + '0')
		} else {
			result += string(temp + '0')
		}
	}
	return Reverse(result)
}



  • 一个数组里只有一个数出现一次,其他元素都出现3次,在不允许使用辅助空间,时间复杂度位O(n) 的情况下找到它
func singleNumber(arr []int) int {
	count := len(arr)
	ones := 0
	twos := 0
	xthrees := 0
	for i := 0; i < count; i++ {
		twos |= ones & arr[i]
		ones ^= arr[i]
		xthrees = ^(ones & twos)
		ones &= xthrees
		twos &= xthrees
	}
	return ones
}

  • 一个数组超过一半以上都是同一个数,求这个数
func findMostNum(nums []int) int {

	candidate := 0
	count := 0
	length := len(nums)
	for i := 0; i < length; i++ {
		if count == 0 {
			candidate = nums[i]
			count = 1
		} else {
			if candidate == nums[i] {
				count++
			} else {
				count--
			}
		}
	}
	return candidate
}

你可能感兴趣的:(go,面试)