leetcode题整理

mergeTwoLists 合并有序链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1==NULL) {return l2;}
        else if (l2 == NULL) {return l1;}
        else {
            if (l1->val <= l2->val) {
                l1->next = mergeTwoLists(l1->next, l2);
                return l1;
            } else {
                l2->next = mergeTwoLists(l1, l2->next);
                return l2;
            }
        }

    }
};

reverseList.cpp 链表反转
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pPre = NULL;
        ListNode* pNode = head;
        ListNode* pReverseHead = NULL;
        if (head== NULL || head->next == NULL) return head;
        while (pNode!= NULL) {
         ListNode* pNext = pNode->next;
         if (pNext == NULL) {
           pReverseHead = pNode;
         }
         pNode->next = pPre;
         pPre = pNode;
         pNode = pNext;
         }
        return pReverseHead;
    }

};

addListNum.cpp 链表相加
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
      ListNode* p = l1;
      ListNode* q = l2;

      ListNode* curNode = new ListNode(0);
      ListNode* phead = curNode;
      int carry = 0;
      while (p!=NULL || q!= NULL) {
        int x = (p!=NULL) ? p->val:0;
        int y = (q!=NULL) ? q->val:0;
        int sum = carry + x + y;
        carry = sum/10;
        curNode->next = new ListNode(sum%10);
        curNode = curNode->next;
        if(p!=NULL) p = p->next;
        if(q!=NULL) q = q->next;
      }
      if(carry==1) {
        curNode->next = new ListNode(carry);
      }
      return phead->next;
    }
};
合并K个排序链表c++
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class cmp{
  public:
    bool operator() (const ListNode* p1,const ListNode* p2){
        return p1->val>p2->val;
    }
};
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* root = new ListNode(-1);
        ListNode* head=root;
        priority_queue<ListNode*,vector<ListNode*>,cmp> q;
        int n = lists.size();
        for(int i=0;i<n;i++){
            if(lists[i]==NULL)continue;
            q.push(lists[i]);
        }
        while(!q.empty()){
            ListNode* node = q.top();
            q.pop();
            root->next = node;
            root = root->next;
            if(node->next != NULL) q.push(node->next);
            
        }
        return head->next;
    }
    
};
combineKlist.py python
#encoding=utf8
class ListNode():
  def __init__(self, val):
    self.val = val
    self.next = None
#heapq 默认小顶堆
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        import heapq
        result = ListNode(-1)
        cur = result
        p = list()
        for i in lists:
            while i:
                heapq.heappush(p, (i.val, i))
                print(p)
                i = i.next

        while p:
            #cur.next = heapq.heappop(p)[1]
            #print("=========",heapq.heappop(p))
            cur.next = heapq.heappop(p)[1]
            print(cur.val,'=====')
            cur = cur.next

        return result.next
if __name__ == '__main__':
  a1 = ListNode(1)
  a1.next =ListNode(2)

  b1 = ListNode(2)
  b1.next =ListNode(3)

  lists = [a1, b1]

  s = Solution()
  c = s.mergeKLists(lists)
  while c:
    print(c.val)
    c = c.next
#二叉树层次遍历
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if root == None:return []
        queue = []
        outlist = []
        queue.append(root)
        while queue:
            res = []
            newqueue = []
            for point in queue:
                res.append(point.val)
                if point.left:
                    newqueue.append(point.left)
                if point.right:
                    newqueue.append(point.right)
            outlist.append(res)
            queue = newqueue
        return outlist
#https://blog.csdn.net/songyunli1111/article/details/81706801
#前序中序后序遍历,bfs,dfs
# -*- coding: utf-8 -*-
import sys
class TreeNode:

    def __init__(self,value):

        self.value=value

        self.left=None

        self.right=None


class Tree_Method:

    def tree_Create(self,arr):

        '''

        利用二叉树的三个组成部分:根节点-左子树-右子树;传入的arr是一个多维列表,每一

        维最大为3,每一维中的内容依次表示根节点-左子树-右子树。然后递归的进行构建

        '''

        length=len(arr)  #计算每一维的大小

        root=TreeNode(arr[0]) #获取每一维的根节点

        if length>=2:         #判断是否有左子树

            root.left=self.tree_Create(arr[1])

        if length>=3:         #判断是否有右子树

            root.right=self.tree_Create(arr[2])

        return root



    def pre_Order(self,root):

        '''前序遍历,遵循根左右的顺序'''

        if root==None:

            return

        print(root.value,end=' ')

        self.pre_Order(root.left)

        self.pre_Order(root.right)



    def mid_Order(self,root):

        '''中序遍历,遵循左根右的顺序'''

        if root==None:

            return

        self.mid_Order(root.left)

        print(root.value,end=' ')

        self.mid_Order(root.right)



    def back_Order(self,root):

        '''遵循左右根的顺序'''

        if root==None:

            return

        self.back_Order(root.left)

        self.back_Order(root.right)

        print(root.value,end=' ')



    def BFS(self,root):

        '''

        广度优先遍历,即从上到下,从左到右遍历

        主要利用队列先进先出的特性,入队的时候

        是按根左右的顺序,那么只要按照这个顺序出队就可以了

        '''

        if root==None:

            return

        queue=[]

        queue.append(root)  #这儿用一个列表模仿入队

        while queue:

            current_node=queue.pop(0)  #将队首元素出队

            print(current_node.value,end=' ')

            if current_node.left:      #判断该节点是否有左孩子

                queue.append(current_node.left)

            if current_node.right:     #判断该节点是否有右孩子

                queue.append(current_node.right)

    def BFSm(self, root):
      '''bfs广度优先搜索,queue先入先出'''
      if root == None:return
      queue = []
      queue.append(root)
      while queue:
        current_node = queue.pop(0)
        print(current_node.value,end=' ')
        if current_node.left:
          queue.append(current_node.left)
        if current_node.right:
          queue.append(current_node.right)

    def DFS(self,root):

        '''

        深度优先遍历,即先访问根结点,然后遍历左子树接着是遍历右子树

        主要利用栈的特点,先将右子树压栈,再将左子树压栈,这样左子树

        就位于栈顶,可以保证结点的左子树先与右子树被遍历

        '''

        if root==None:

            return

        stack=[]

        stack.append(root)      #这儿用一个列表模仿入队

        while stack:

            current_node=stack.pop()  #将栈顶元素出栈

            print(current_node.value,end=' ')

            if current_node.right:    #判断该节点是否有右孩子,有就入栈

                stack.append(current_node.right)

            if current_node.left:     #判断该节点是否有左孩子,有就入栈。两个判断的顺序不能乱

                stack.append(current_node.left)


if __name__=="__main__":

    arr=[2,[3,[4],[5]],[2,[4,[7]],[3]]]

    op=Tree_Method()

    tree=op.tree_Create(arr)

    print('前序遍历:',end='')

    op.pre_Order(tree)

    print()

    print('中序遍历:',end='')

    op.mid_Order(tree)

    print()

    print('后序遍历:',end='')

    op.back_Order(tree)

    print()
    print('广度优先遍历:',end='')

    op.BFSm(tree)

    print()
    sys.exit(0)

    print('深度优先遍历:',end='')

    op.DFS(tree)
#两个有序数组查找中位数
'''
两个有序数组求中位数,问题一般化为,求两个有序数组的第k个数,当k = (m+n)/2时为原问题的解。
怎么求第k个数?分别求出第一个和第二个数组的第 k / 2个数 a 和 b,然后比较 a 和 b,当a < b ,说明第 k 个数位于 a数组的第 k / 2个数后半段,或者b数组的 第 k / 2 个数前半段,问题规模缩小了一半,然后递归处理就行。
时间复杂度是 O(log(m+n))'''
class Solution:
    """
    @param A: An integer array.
    @param B: An integer array.
    @return: a double whose format is *.5 or *.0
    """
 
    def findMedianSortedArrays(self, A, B):
        n = len(A) + len(B)
        if n % 2 == 1:
            return self.findKth(A, B, n / 2 + 1)
        else:
            smaller = self.findKth(A, B, n / 2)
            bigger = self.findKth(A, B, n / 2 + 1)
            return (smaller + bigger) / 2.0
 
    def findKth(self, A, B, k):
        if len(A) == 0:
            return B[int(k - 1)]
        if len(B) == 0:
            return A[int(k - 1)]
        if k == 1:
            return min(A[0], B[0])
 
        a = A[int(k / 2) - 1] if len(A) >= k / 2 else None
        b = B[int(k / 2) - 1] if len(B) >= k / 2 else None
 
        if b is None or (a is not None and a < b):
            return self.findKth(A[int(k / 2):], B, int(k - k / 2))
        return self.findKth(A, B[int(k / 2):], int(k - k / 2))
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        //处理任何一个nums为空数组的情况
        if (m == 0) {
            if (n % 2 != 0)
                return 1.0 * nums2[n / 2];
            return (nums2[n / 2] + nums2[n / 2 - 1]) / 2.0;
        }
        if (n == 0) {
            if (m % 2 != 0)
                return 1.0 * nums1[m / 2];
            return (nums1[m / 2] + nums1[m / 2 - 1]) / 2.0;
        }
        int total = m + n;
        //总数为奇数,找第 total / 2 + 1 个数
        if ((total & 1) == 1) {
            return find_kth(nums1, 0, nums2, 0, total / 2 + 1);
        }
        //总数为偶数,找第 total / 2 个数和第total / 2 + 1个数的平均值
        return (find_kth(nums1, 0, nums2, 0, total / 2) + find_kth(nums1, 0, nums2, 0, total / 2 + 1)) / 2.0;

    }

    //寻找a 和 b 数组中,第k个数字
    double find_kth(int[] a, int a_begin, int[] b, int b_begin, int k) {
        //当a 或 b 超过数组长度,则第k个数为另外一个数组第k个数
        if (a_begin >= a.length)
            return b[b_begin + k - 1];
        if (b_begin >= b.length)
            return a[a_begin + k - 1];
        //k为1时,两数组最小的那个为第一个数
        if (k == 1)
            return Math.min(a[a_begin], b[b_begin]);

        int mid_a = Integer.MAX_VALUE;
        int mid_b = Integer.MAX_VALUE;
        //mid_a / mid_b 分别表示 a数组、b数组中第 k / 2 个数
        if (a_begin + k / 2 - 1 < a.length)
            mid_a = a[a_begin + k / 2 - 1];
        if (b_begin + k / 2 - 1 < b.length)
            mid_b = b[b_begin + k / 2 - 1];
        //如果a数组的第 k / 2 个数小于b数组的第 k / 2 个数,表示总的第 k 个数位于 a的第k / 2个数的后半段,或者是b的第 k / 2个数的前半段
        //由于范围缩小了 k / 2 个数,此时总的第 k 个数实际上等于新的范围内的第 k - k / 2个数,依次递归
        if (mid_a < mid_b)
            return find_kth(a, a_begin + k / 2, b, b_begin, k - k / 2);
        //否则相反
        return find_kth(a, a_begin, b, b_begin + k / 2, k - k / 2);
    }
}


作者:horanol
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/zhen-zheng-ologmnde-jie-fa-na-xie-shuo-gui-bing-pa/
已知前序中序求后序,
核心是找出跟节点,和左部分子树,这样递归才能走起来
#encoding=utf8
class TreeNode:
  def __init__(self,x):
    self.val = x
    self.left = None
    self.right = None

class Solution:
  # 返回构造的TreeNode根节点
  def reConstructBinaryTree(self, pre, tin):
    # write code here
    if len(pre) == 0:
      return None
    root = TreeNode(pre[0])
    ti_index = tin.index(pre[0])
    root.left = self.reConstructBinaryTree(pre[1:1+ti_index], tin[:ti_index])
    root.right = self.reConstructBinaryTree(pre[1+ti_index:], tin[ti_index+1:])
    return root
  def PostTraversal(self,root):  #后序遍历
    if root != None:
      self.PostTraversal(root.left)
      self.PostTraversal(root.right)
      print(root.val)
pre=[1,2,4,7,3,5,6,8]
tin=[4,7,2,1,5,3,8,6]
print('pre:',pre)
print('tin:',tin)
S=Solution()
root=S.reConstructBinaryTree(pre,tin)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值