构造用三叉链表表示的二叉树_中级算法链表+树和图+回溯算法+排序和搜索

整天除了看招聘和数据分析的课程,唯一的乐趣就是刷题了,本计划昨天更新链表+树和图,由一点事耽误了;本次更新有点多,而且这类中级的题目也很简单,就不在此写解题思路了,看程序可以秒懂的。

链表


题目一:两树相加

内容:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。    ‍

程序:

# Definition for singly-linked list.

# class ListNode:

#     def __init__(self, x):

#         self.val = x

#         self.next = None

class Solution:

    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:

        l3 = ListNode(0)

        A = l1

        B = l2

        C = l3

        Jin = 0

        while A and B:

            tem = A.val + B.val + Jin

            if tem 10:

                C.next = ListNode(tem)

                Jin = 0

            else:

                Jin = 1

                C.next = ListNode(tem % 10)

            A = A.next

            B = B.next

            C = C.next

        print(A)

        while A:

            tem = A.val + Jin

            if tem 10:

                C.next = ListNode(tem)

                C.next.next = A.next

                return l3.next

            else:

                Jin = 1

                C.next = ListNode(tem % 10)

            A = A.next

            C = C.next

        while B:

            tem = B.val + Jin

            if tem 10:

                C.next = ListNode(tem)

                C.next.next = B.next

                return l3.next

            else:

                Jin = 1

                C.next = ListNode(tem % 10)

            B = B.next

            C = C.next

        if Jin == 1:

            C.next = ListNode(1)

        return l3.nex

题目二:奇偶链表

内容:

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。    ‍

程序:

# Definition for singly-linked list.

# class ListNode:

#     def __init__(self, val=0, next=None):

#         self.val = val

#         self.next = next

class Solution:

    def oddEvenList(self, head: ListNode) -> ListNode:

        if not head:

            return None

        l1 = ListNode()

        l2 = ListNode()

        A = l1

        B = l2

        cur = head

        tem = 1

        while cur:

            if tem % 2 == 1:

                A.next = ListNode(cur.val)

                A = A.next

            else:

                B.next = ListNode(cur.val)

                B = B.next

            tem += 1

            cur = cur.next

            # A = A.next

            # B = B.next

        A.next = l2.next

        return l1.next

#####################

##方法二

        # if not head:

        #     return None

        # cur = head

        # tem = 1

        # count = 0

        # New = head

        # while cur.next:

        #     count += 1

        #     cur = cur.next

        # if count <= 1:

        #     return head

        # while New and tem <= count + 1:

        #     if tem % 2 != 0:

        #         pre = New

        #         New = New.next

        #         tem += 1

        #     else:

        #         cur.next = ListNode(New.val)

        #         pre.next = New.next

        #         New = pre.next

        #         cur = cur.next

        #         tem += 1

        # return head

问题三:相交链表

内容:

编写一个程序,找到两个单链表相交的起始节点。

12d5251549965b28001abf100fae82aa.png    ‍

本题还是很有意思的,这种题目的解题思路在于---有缘千里来相会;

送给准备过七夕的小伙伴    ‍

程序:

# Definition for singly-linked list.

# class ListNode:

#     def __init__(self, x):

#         self.val = x

#         self.next = None

class Solution:

    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:

        """

        有缘千里来相会

        """

        if not headA or not headB:

            return None

        if headA == headB:

            return headB

        A = headA

        B = headB

        while A != B:

            if not A:

                A = headB

            else:

                A = A.next

            if not B:

                B = headA

            else:

                B = B.next

        if A:

            return A

        else:

            return A


树和图

问题一:二叉树的中序遍历

内容:

给定一个二叉树,返回它的中序 遍历。    ‍

程序:

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    def inorderTraversal(self, root: TreeNode) -> List[int]:

        self.res = []

        def func(root):

            if not root:

                return

            func(root.left)

            self.res.append(root.val)

            func(root.right)

        func(root)

        return self.res

问题二:二叉树的锯齿形层次遍历

内容:

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。    ‍

程序:

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:

        res = []

        if not root:

            return res

        queue = [root]

        A = 0

        while queue:

            tem = []

            r = []

            for cur in queue:

                r.append(cur.val)

                if cur.right:

                    tem.append(cur.right)

                if cur.left:

                    tem.append(cur.left)

            if A % 2 == 1:

                res.append(r)

            else:

                res.append(r[::-1])

            A += 1

            queue = tem

        return res

问题三:从前序与中序遍历构造二叉树

内容:

根据一棵树的前序遍历与中序遍历构造二叉树。

程序:

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:

        if not preorder:

            return

        res = TreeNode(preorder[0])

        idex = inorder.index(preorder[0])

        res.left = self.buildTree(preorder[1:idex+1], inorder[:idex])

        res.right = self.buildTree(preorder[idex+1:],inorder[idex+1:])

        return res

问题四:填充每个节点的下一个右侧节点指针

内容:

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {

  int val;

  Node *left;

  Node *right;

  Node *next;

}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。    ‍

程序:

"""

# Definition for a Node.

class Node:

    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):

        self.val = val

        self.left = left

        self.right = right

        self.next = next

"""

class Solution:

    def connect(self, root: 'Node') -> 'Node':

        if not root:

            return

        queue = [root]

        root.next = None

        while queue:

            tem = []

            for cur in queue:

                if cur.left:

                    tem.append(cur.left)

                    if len(tem) == 1:

                        A = tem[0]

                    else:

                        A.next = tem[-1]

                        A = A.next

                    tem.append(cur.right)

                    A.next = tem[-1]

                    A = A.next

            try:

                A.next = None

            except:

                return root

            queue = tem

        return root

问题五:二叉搜索树中第K小的元素

内容:

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。    ‍

程序:

# Definition for a binary tree node.

# class TreeNode:

#     def __init__(self, val=0, left=None, right=None):

#         self.val = val

#         self.left = left

#         self.right = right

class Solution:

    def kthSmallest(self, root: TreeNode, k: int) -> int:

        self.res= []

        def func(root):

            if not root:

                return

            func(root.left)

            # self.res.append(root.val)

            if len(self.res) == k:

                return

            else:

                self.res.append(root.val)

            func(root.right)

        func(root)

        return self.res[-1]

问题六:岛屿数量

内容:

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。    ‍

程序:

class Solution:

    def numIslands(self, grid: List[List[str]]) -> int:

        def DFS(x,y,grid):

            grid[x][y] = 'X'

            if 0 <= x len(grid) and 0 <= y len(grid[0]):

                for i,j in [[1,0],[-1,0],[0,1],[0,-1]]:

                    if 0 <= x+i len(grid) and 0 <= y+j len(grid[0]) and grid[x+i][y+j] == '1':

                        DFS(x+i,y+j,grid)

            else:

                return

        res = 0

        for i in range(len(grid)):

            for j in range(len(grid[0])):

                if grid[i][j] == '1':

                    res += 1

                    DFS(i,j,grid)

        return res


回溯算法

问题一:电话号码的字母组合

内容:

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。    ‍

程序:

class Solution:

    def letterCombinations(self, digits: str) -> List[str]:

        if not digits:

            return []

        dic = {'2':'abc',

                '3':'def',

                '4':'ghi',

                '5':'jkl',

                '6':'mno',

                '7':'pqrs',

                '8':'tuv',

                '9':'wxyz'}

        self.res = []

        def DFS(digits,k,queue):

            if len(queue) == len(digits):

                self.res.append(queue)

                return

            if k >= len(digits):

                return

            for i in range(k,len(digits)):

                if len(queue)!= k:

                    return

                for j in range(len(dic[digits[i]])):

                    queue += dic[digits[i]][j]

                    DFS(digits,k + 1,queue)

                    if j == len(dic[digits[i]]) - 1:

                        continue

                    queue = queue[:-1]

        DFS(digits,0,'')

        return self.res

问题二:括号生成

内容:

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。    ‍

程序:

class Solution:

    def generateParenthesis(self, n: int) -> List[str]:

        left = 0

        right = 0

        self.res = []

        def DFS(left,right,n,queue):

            if right > left:

                return

            if left > n: return

            if len(queue) == 2 * n :

                if queue not in self.res:

                    self.res.append(queue + '')

                return 

            for i in range(1,n-left+1):

                DFS(left +i,right,n, queue + '('*i)

            for j in range(1,n-right+1):

                DFS(left,right+j,n,queue + ')'*j )

        DFS(left,right,n,'')

        return self.res

问题三:全排列

内容:

给定一个 没有重复 数字的序列,返回其所有可能的全排列。    ‍

程序:

class Solution:

    def permute(self, nums: List[int]) -> List[List[int]]:

        nums = sorted(nums)

        end = nums[::-1]

        res = []

        while nums != end:

            res.append(nums+[])

            for i in range(len(nums)-1,-1,-1):

                if i == len(nums)-1:

                    continue

                else:

                    if nums[i] 1]:

                        for j in range(len(nums[i+1:])-1,-1,-1):

                            if nums[i+1:][j] > nums[i]:

                                nums[i], nums[i+1+j] = nums[i+1+j], nums[i]

                                nums[i+1:] = sorted(nums[i+1:])

                                break

                        break

        res.append(end)        

        return res

        #############   ################

        # self.res = []

        # def All_sorted(nums,k):

        #     if k == len(nums):

        #         return

        #     for i in range(k,len(nums)):

        #         nums[k] ,nums[i] = nums[i], nums[k]

        #         if nums not in self.res:

        #             self.res.append(nums+[])

        #         All_sorted(nums,k+1)

        #         nums[k],nums[i] = nums[i], nums[k]

        # All_sorted(nums,0)

        # return self.res

问题四:子集

内容:

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

程序:

class Solution:

    def subsets(self, nums: List[int]) -> List[List[int]]:

        self.res = []

        def DFS(nums,i,queue):

            if i >= len(nums):

                self.res.append(queue + [])

                return

            queue.append(nums[i])

            DFS(nums,i+1,queue)

            queue.pop()

            DFS(nums,i+1,queue)

        DFS(nums,0,[])

        return self.res

问题五:单词搜索

内容:

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。    ‍

程序:

class Solution:

    def exist(self, board: List[List[str]], word: str) -> bool:

        def DFS(i,j,board,visit,k):

            if 0 <= i len(board) and 0 <= j len(board[0]) and k <= len(word):

                if k == len(word):

                    return True

                for x,y in [[1,0],[-1,0],[0,1],[0,-1]]:

                    if 0 <= i+x len(board) and 0 <= j+y len(board[0]) and board[i+x][j+y] == word[k] and [x+i,j+y] not in visit:

                        if k == len(word) - 1:

                            return True

                        if DFS(i+x,j+y,board,visit + [[i+x,j+y]],k+1):

                            return True

            else:

                return False

        for i in range(len(board)):

            for j in range(len(board[0])):

                if board[i][j] == word[0]:

                    visit = [[i,j]]

                    if DFS(i,j,board,visit,1):

                        return True

        return False


排序和搜索

问题一:颜色分类

内容:

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:

不能使用代码库中的排序函数来解决这道题。

程序:

class Solution:

    def sortColors(self, nums: List[int]) -> None:

        """

        Do not return anything, modify nums in-place instead.

        """

        i = 0

        j = len(nums) - 1

        while i 

            if nums[i] == 0:

                i += 1

            elif nums[i] == 1:

                if nums[j] == 2:

                    j -= 1

                elif nums[j] == 0:

                    nums[i], nums[j] = nums[j], nums[i]

                    i += 1

                else:

                    state = True

                    for k in range(i+1,j):

                        if nums[k] == 0 or nums[k] == 2:

                            state = False

                            if nums[k] == 0:

                               nums[k], nums[i] = nums[i], nums[k]

                               i += 1

                               break

                            if nums[k] == 2:

                                nums[k], nums[j] = nums[j], nums[k]

                                j -= 1

                                break

                    if state:

                        break

            else:

                if nums[j] == 2:

                    j-= 1

                else:

                    nums[i], nums[j] = nums[j], nums[i]

                    j -= 1

问题二:前K个高频元素

内容:

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。    ‍

程序:

class Solution:

    def findKthLargest(self, nums: List[int], k: int) -> int:

        # nums = sorted(nums,reverse=True)

        nums = sorted(nums)[::-1]

        return nums[k-1]

问题三:数组中的第K个最大元素

内容:

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

程序:

class Solution:

    def findKthLargest(self, nums: List[int], k: int) -> int:

        # nums = sorted(nums,reverse=True)

        nums = sorted(nums)[::-1]

        return nums[k-1]

问题四:寻找峰值

内容:

峰值元素是指其值大于左右相邻值的元素。

给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞。    ‍

程序:

class Solution:

    def findPeakElement(self, nums: List[int]) -> int:

        tem = float('inf')

        nums = collections.deque(nums)

        nums.appendleft(tem)

        nums.append(float('-inf'))

        for i in range(1,len(nums)-1):

            if nums[i-1] and nums[i] > nums[i+1]:

                return i-1

        return 0

问题五:在排序数组中查找元素的第一个和最后一个位置

内容:

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]。    ‍

程序:

class Solution:

    def searchRange(self, nums: List[int], target: int) -> List[int]:

        try:

            idx = nums.index(target)

            res = []

            res.append(idx)

            for i in range(idx+1,len(nums)):

                if nums[i] !=target:

                    res.append(i-1)

                    return res

            res.append(len(nums)-1)

            return res

        except:

            return [-1,-1]

问题六:合并区间

内容:

给出一个区间的集合,请合并所有重叠的区间。    ‍

程序:

class Solution:

    def merge(self, intervals: List[List[int]]) -> List[List[int]]:

        if not intervals:

            return []

        s = sorted(intervals, key = lambda x :x[0])

        print(s)

        tem = s[0]

        res = []

        for i in range(1,len(s)):

            if tem[1] 0]:

                res.append(tem)

                tem = s[i]

            else:

                if tem[1] > s[i][1]:

                    continue

                else:

                    tem[1] = s[i][1]

        res.append(tem)

        return res    ‍

问题七:搜索旋转排序数组

内容:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

程序:

class Solution:

    def search(self, nums: List[int], target: int) -> int:

        try:

            return nums.index(target)

        except:

            return -1

问题八:搜索二维矩阵

内容:

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

每行的元素从左到右升序排列。

每列的元素从上到下升序排列。    ‍

程序:

class Solution:

    def searchMatrix(self, matrix, target):

        """

        :type matrix: List[List[int]]

        :type target: int

        :rtype: bool

        """

        for i in range(len(matrix)):

            if not matrix[i]:

                return False

            if matrix[i][-1] 

                continue

            if matrix[i][0] > target:

                continue

            if target in matrix[i]:

                return True

            else:

                continue

        return False

数据结构源码C语言描述续,本篇描述了二叉树三叉链表结构及其操作,以及测试程序: //创建二叉树结点 TriTreeNode *CreateTriTreeNode(char data); //给二叉树添加结点,用于创建二叉树 int AddTriTreeNode(char data, TriTreeNode *newTriNode); //创建二叉树 TriTreeNode *CreateTriTree(); //计算二叉树的高度 int GetTriTreeDepth(TriTreeNode *triTree); //插入结点(连接两棵二叉树),这个结点(二叉树)root不相交; //newTriNode可以是一个结点也可以是一棵二叉树 int InsertChildTriNode(TriTreeNode *newTriNode, TriTreeNode *root); //获取根结点 TriTreeNode *GetTriTreeRoot(TriTreeNode *triTree); //判断二叉树是否为空 int IsTriTreeEmpty(TriTreeNode *triTree); //获取二叉树中某一个结点的左孩子结点 void GetLeftChildFromTriTree(TriTreeNode *triTree, TriTreeNode *triNode, TriTreeNode *lChild); //获取二叉树中某一个结点的右孩子结点 void GetRightChildFromTriTree(TriTreeNode *triTree, TriTreeNode *triNode, TriTreeNode *rChild); //获取二叉树某一个指定结点父节点 int GetTriTreeParent(TriTreeNode *root, TriTreeNode *triNode, TriTreeNode *parentNode); //删除二叉树,某一个指定结点的左或右子 void DeleteChildFromTriTree(TriTreeNode *root, TriTreeNode *triNode, int flag); //销毁二叉树 void DestroyTriTree(TriTreeNode *TriTree); //先序遍历(DRL), 先序遍历按照既定算法遍历出来将是一个无序列表 void PreOrderTraversTriTreeDRL(TriTreeNode *TriTree); //先序遍历(DLR), 先序遍历按照既定算法遍历出来将是一个无序列表 void PreOrderTraversTriTreeDLR(TriTreeNode *TriTree); //中序遍历(LDR),遍历结果应该是一个从小到大的有序排列 void InOrderTraversTriTreeLDR(TriTreeNode *TriTree); //中序遍历(RDL),遍历结果是一个从大到小的有序排列 void InOrderTraversTriTreeRDL(TriTreeNode *triTree); //后续遍历(LRD) void PostOrderTraversTriTreeLRD(TriTreeNode *TriTree); //后续遍历(RLD), void PostOrderTraversTriTreeRLD(TriTreeNode *TriTree);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值