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
}

浙公网安备 33010602011771号