leetcode

 


二叉搜索树

所谓的二叉搜索树(BST),就是满足二叉树中每个节点大于左子树小于右子树的二叉树,而二叉树搜索树的插入对比它的这一特征,插入就能够很好的解决,判断当前节点是否为空,为空直接插入数字并返回,不为空,与该节点的val进行对比,进行循环递归,直到该节点的值大于val并且该节点左子树为空插入val,或者该节点的值小于val并且右子树为空插入val。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func insertIntoBST(root *TreeNode, val int) *TreeNode {
    if root == nil {
     return &TreeNode{Val: val}
    }
    p := root
    for p != nil{
        if p.Val < val {
                if p.Right != nil {
                    p = p.Right
                }else {
                    p.Right = &TreeNode{Val: val}
                    break
                }
        }else {
            if p.Left != nil {
                p = p.Left
            }else {
                p.Left = &TreeNode{Val: val}
                break
            }
        }
    }
   
    return root
}

两数相加

题目描述两个非空链表相加,由于是逆序存贮,所以只需要用一个变量存贮进位就可以了,当两个链表都为空并且进位也为0的时候,表示两个链表相加完毕。最后返回头节点。

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    return addTwoNumber(l1, l2, 0)
}

func addTwoNumber(l1 *ListNode, l2 *ListNode, add int) *ListNode{
    if l1 == nil && l2 == nil && add == 0 {
        return nil
    }

    if l1 != nil {
        add += l1.Val
        l1 = l1.Next
    }
    if l2 != nil {
        add += l2.Val
        l2 = l2.Next
    }

    node := ListNode{
        Val: add % 10,
        Next: addTwoNumber(l1, l2, add / 10),
    }

    return &node
}

无重复最长子串

给定一个字串,求出最长不重复的字串。模拟一下求解最长不重复子串的过程,将第一个字符存入map中,在以第一个字符为起点循环判断存入字符,当一个字符第二次出现时,当前位置减去起点的位置,这中间就是无重复字串的长度,给定一个变量ans存入长度最大值。当前这一个无重复字串就相当于一个滑动框,我们起点+1,更换起点,滑动框右边在进行判断查找,重复以上操作,找到一个无重复字串的最大值。

func lengthOfLongestSubstring(s string) int {
    mp := map[byte]int{}
    rk := -1
    ans := 0
    for i := 0; i < len(s); i++ {
        if i != 0 {
            delete(mp, s[i-1])
        }
        for rk+1 < len(s) && mp[s[rk+1]]==0 {
            mp[s[rk+1]]++
            rk++
        }
        ans = max(ans, rk - i +1)
    }
    return ans
}
func max(a, b int) int {
    if a <= b {
        return b
    }else {
        return a
    }
}

四数之和

给定一个一维数组,求出这个数组之中满足4个数之和等于target的数组集合,最常想到的方法是先对数组排序,在进行四重循环,得到满足条件的数组,在对数组进行去从。我在这里是写的一个check函数进行去从,也可以在循环中添加条件,即同一重循环中,在满足条件后,当num[i]==num[i-1]时 continue。

var ans [][]int
func fourSum(nums []int, target int) [][]int {
	ans = [][]int{}
	sort.Ints(nums)
	for i := 0; i < len(nums); i++ {
		for j := i+1; j < len(nums); j++ {
			for k := j+1; k < len(nums); k++ {
				for l := k+1; l < len(nums); l++ {
					if nums[i] + nums[j] + nums[k] + nums[l] > target {
						break
					}
					if nums[i] + nums[j] + nums[k] + nums[l] == target {
						if check([]int{nums[i], nums[j], nums[k], nums[l]}){
							ans = append(ans, []int{nums[i], nums[j], nums[k], nums[l]})
						}

					}
				}

			}

		}
	}
	return ans
}
func check(nums []int) bool{
    flag := 0
    for i := 0; i < len(ans); i++ {
        for j :=0; j < len(nums); j++{
            if ans[i][j] == nums[j] {
                flag = 1
            }else {
                flag = 0
                break
            }
        }
        if flag == 1 {
            return false
        }
    }
    return true
}

当然这种算法的复杂度是O(n4)。在这个基础上我们可以使用双指针的方法,枚举i,j 在进行双指针判断num[i]+num[j]+num[left]+num[right]==target 得到满足条件的数组。在这基础上我们可以在同一重循环中在进行优化,在i这层循环中,如果num[i]+num[n-1]+num[n-2]+num[n-3]<target 可以直接进行下一次循环,同理在j这一层循环中,如果num[i]+num[n-1]+num[n-2]+num[j]<target,可以直接进行下一次循环。进而时间复杂度优化为O(n3)

func fourSum1(nums []int, target int) [][]int {
	sort.Ints(nums)
	ans = [][]int{}
	n := len(nums)
	for i := 0; i < n-3 && nums[i]+nums[i+1]+nums[i+2]+nums[i+3] <= target; i++ {
		if i > 0 && nums[i] == nums[i-1] ||  nums[i]+nums[n-1]+nums[n-2]+nums[n-3] < target {
			continue
		}
		for j := i+1; j < n-2 && nums[j]+nums[j+1]+nums[j+2]+nums[i] <= target; j++ {
			if j > i+1 && nums[j] == nums[j-1] || nums[i]+nums[n-1]+nums[n-2]+nums[j] < target {
				continue
			}
			for left, right := j+1, n-1; left < right; {
				if nums[i] + nums[j] + nums[left] + nums[right] == target {
					ans = append(ans, []int{nums[i], nums[j], nums[left], nums[right]})
					for ;nums[left]==nums[left+1];left++ {
					}
					for ;nums[right]==nums[right-1];right-- {
					}
					left++
					right--
				}else if nums[i] + nums[j] + nums[left] + nums[right] < target {
					left++
				}else {
					right--
				}

			}

		}
	}
	return ans
}

三数之和

同四数之和,进行一重循环加上双指针进行优化,从而在O(n2)的复杂度上得到答案

func threeSum(nums []int) [][]int {
    ans := [][]int{}
    sort.Ints(nums)
    n := len(nums)
    for i:=0; i < n-2 && nums[i]+nums[i+1]+nums[i+2] <= 0; i++ {
        if i > 0 && nums[i] == nums[i-1] || nums[i]+nums[n-1]+nums[n-2] < 0 {
            continue
        }
        for left, right := i+1, n-1; left < right; {
            if sum := nums[i]+nums[left]+nums[right]; sum == 0 {
                ans = append(ans, []int{nums[i], nums[left], nums[right]})
                for left++; left < right && nums[left]==nums[left-1]; left++ {
                }
                for right--; left < right && nums[right] == nums[right+1]; right--{
                }
            }else if sum < 0 {
                left++
            }else {
                right--
            }
        }
    }
    return ans
}

  

 

posted @   cxylsy  阅读(135)  评论(0)    收藏  举报
努力加载评论中...
页脚Html代码
点击右上角即可分享
微信分享提示