1.两数之和
code:
func twoSum(nums []int, target int) []int {
var res []int
record := make(map[int]int)
for i,num := range nums {
if idx,ok := record[target - num]; ok {
return []int{idx,i}
}
record[num] = i
}
return res
}
思路:
顺序扫描数组,对每一个元素,在 map 中找能组合给定值的另一半数字,如果找到了,直接返回 2 个数字的下标即可。如果找不到,就把这个数字存入 map 中,等待扫到“另一半”数字的时候,再取出来返回结果。
2.两数相加
code:
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
head := &ListNode{Val: 0}
n1, n2, carry, cur := 0, 0, 0, head
for l1 != nil || l2 != nil || carry != 0 {
if l1 == nil {
n1 = 0
} else {
n1 = l1.Val
l1 = l1.Next
}
if l2 == nil {
n2 = 0
} else {
n2 = l2.Val
l2 = l2.Next
}
cur.Next = &ListNode{
Val: (n1 + n2 + carry) % 10,
}
carry = (n1 + n2 + carry) / 10
}
return head.Next
}
思路:
看代码就行,加个头结点比较方便
3. 无重复最长子串
code:
func lengthOfLongestSubstring(s string) int {
heap := make(map[uint8]int)
i, j := 0, 0
res := 0
for ; j < len(s); j++ {
heap[s[j]]++
for heap[s[j]] > 1 {
heap[s[i]] -= 1
i += 1
}
if j-i+1 > res {
res = j - i + 1
}
}
return res
}
思路:
双指针问题,考虑是否具有单调性
5.最长回文子串
code:
func longestPalindrome(s string) string {
var res string
for i := 0; i < len(s); i++ {
l, r := i-1, i+1
for l >= 0 && r < len(s) && s[l] == s[r] {
l -= 1
r += 1
}
if r-l-1 > len(res) {
res = s[l+1 : r]
}
l, r = i, i+1
for l >= 0 && r < len(s) && s[l] == s[r] {
l -= 1
r += 1
}
if r-l-1 > len(res) {
res = s[l+1 : r]
}
}
return res
}
思路:
以某个点为中心,分别枚举奇数串和偶数串 on2
6.有序数组的中位数
code:
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
total := len(nums1) + len(nums2)
if total%2 == 0 {
left := find(nums1, 0, nums2, 0, total/2)
right := find(nums1, 0, nums2, 0, total/2+1)
return (left + right) / 2.0
}
return find(nums1, 0, nums2, 0, total/2+1)
}
func find(nums1 []int, i int, nums2 []int, j int, k int) float64 {
if len(nums1)-i > len(nums2)-j {
return find(nums2, j, nums1, i, k)
}
if len(nums1) == i {
return float64(nums2[j+k-1])
}
if k == 1 {
return min(nums1[i], nums2[j])
}
si := i + k/2
if si > len(nums1) {
si = len(nums1)
}
sj := j + k/2
if nums1[si-1] < nums2[sj-1] {
return find(nums1, si, nums2, j, k-(si-i))
} else {
return find(nums1, i, nums2, sj, k-(sj-j))
}
}
func min(a int, b int) float64 {
if a > b {
return float64(b)
}
return float64(a)
}
思路:
找出第K大的数字,递归每次砍一半
7.整数反转
code:
func reverse(x int) int {
res := 0
for x != 0 {
res =res * 10 + x % 10
if float64(res) > math.Pow(2,31) - 1 || float64(res) < -math.Pow(2,31) {
return 0
}
x /= 10
}
return res
}
8.字符串转整数
code:
import (
"math"
)
func myAtoi(s string) int {
var res int
min, max := -int(math.Pow(2, 31)), int(math.Pow(2, 31)-1)
s = removePreSpace(s)
s, positive := isPositive(s)
for _, c := range s {
ch := c - '0'
if ch < 0 || ch > 9 {
break
}
res = res*10 + int(ch)
if positive && res > max {
return max
}
if !positive && -res < min {
return min
}
}
if positive {
return res
}
return -res
}
// removePreSpace 删除前导空格
func removePreSpace(s string) string {
idx := 0
for _, c := range s {
if c != ' ' {
break
}
idx += 1
}
return s[idx:]
}
func isPositive(s string) (string, bool) {
if len(s) == 0 {
return s, false
}
if s[0] == '+' {
return s[1:], true
}
if s[0] == '-' {
return s[1:], false
}
return s, true
}
思路:
纯细节和边界
9.回文数
code:
func isPalindrome(x int) bool {
if x < 0 {
return false
}
if x == 0 {
return true
}
if x%10 == 0 {
return false
}
s := 0
for s <= x {
s = s*10 + x%10
if s == x || s == x / 10 {
return true
}
x = x / 10
}
return false
}
思路:
注意判断奇偶