华为手撕代码+剑指offer总结 (python+c语言)

文章目录

1.华为手撕代码总结

1.1排序问题

  • 冒泡排序
def bubbleSort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr
  • 快排

思路:快速排序基本思想是:如序列[6,8,1,4,3,9],选择6作为基准数。从右向左扫描,寻找比基准数小的数字为3,交换6和3的位置,[3,8,1,4,6,9],接着从左向右扫描,寻找比基准数大的数字为8,交换6和8的位置,[3,6,1,4,8,9]。重复上述过程,直到基准数左边的数字都比其小,右边的数字都比其大。然后分别对基准数左边和右边的序列递归进行上述方法。详细可见:https://www.jianshu.com/p/2b2f1f79984e

def q_sort(L, left, right):
    if left < right:
        pivot = Partition(L, left, right)
        q_sort(L, left, pivot - 1)
        q_sort(L, pivot + 1, right)
    return L

def Partition(L, left, right):
    pivotkey = L[left]
    while left < right:
        while left < right and L[right] >= pivotkey:
            right -= 1
        L[left] = L[right]
        while left < right and L[left] <= pivotkey:
            left += 1
        L[right] = L[left]

    L[left] = pivotkey
    return left

1.2链表求和

题目解析:
3->1->5->null 
5->9->2->null

3+5=8
1+9=10,得到的进位1到下一个节点,第二个节点为0
1(上一个节点的进位)+5+2=8
结果为:
8->0->8->null

代码实现:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addLists(self, l1, l2):
        #判断是否某一链表为None,是返回另一条
        if l1==None:return l2
        if l2 == None:return l1
        h1=l1
        h2=l2
        #只有两个链表的下一个节点数都为None,退出循环
        while h1.next is not None or h2.next is not None:
            #若只有一条链表的下一个节点为None,补充为0,不影响后续的加法结果
            if h1.next ==None:h1.next=ListNode(0)
            if h2.next ==None:h2.next=ListNode(0)
            h1.val=h1.val+h2.val
            #当加结果>=10,当前结果节点为个位数,下一个节点+1
            if h1.val>=10:
                h1.val=h1.val%10
                h1.next.val+=1
            h1=h1.next
            h2=h2.next
        else:
            h1.val=h1.val+h2.val
            #链表尾部的计算,如果>=10,则在尾部再添加一个节点
            if h1.val>=10:
                h1.val=h1.val%10
                h1.next=ListNode(1)
        return l1

1.3树的前中后序遍历(递归/循环写法)

  • 递归
class Solution:
    def inorderTraversal(self, root):   #中序遍历
        if not root:
            return [] 
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

    def preorderTraversal(self, root):  #前序遍历
        if not root:
            return [] 
        return  [root.val] + self.inorderTraversal(root.left) + self.inorderTraversal(root.right)
        
    def postorderTraversal(self, root):  #后序遍历
        if not root:
            return [] 
        return  self.inorderTraversal(root.left) + self.inorderTraversal(root.right) + [root.val]
  • 循环实现

原理详细解释:https://www.cnblogs.com/bjwu/p/9284534.html

class Solution:
    def inorderTraversal(self, root):    #中序遍历
        stack = []    #用栈实现
        sol = []      #结果
        curr = root    #节点运动位置
        while stack or curr:
            if curr:
                stack.append(curr)
                curr = curr.left
            else:
                curr = stack.pop()
                sol.append(curr.val)
                curr = curr.right
        return sol
        
     def preorderTraversal(self, root):   # 前序遍历
        stack = []
        sol = []
        curr = root
        while stack or curr:
            if curr:
                sol.append(curr.val)
                stack.append(curr.right)
                curr = curr.left
            else:
                curr = stack.pop()
        return sol
        
    def postorderTraversal(self, root):    # 后序遍历
        stack = []
        sol = []
        curr = root
        while stack or curr:
            if curr:
                sol.append(curr.val)
                stack.append(curr.left)
                curr = curr.right
            else:
                curr = stack.pop()
        return sol[::-1]

1.4树的链表化

<table>
    <tr>
        <td ><center><img src="https://img-blog.csdnimg.cn/20190511112024837.png" >输入 </center></td>
        <td ><center><img src="https://img-blog.csdnimg.cn/20190511112042474.png" >输出</center></td>
    </tr>

思路:对于每一颗子树进行后序遍历,将右子树连接到左子树的右子树上,将左子树连接到根节点的右子树上;递归进行遍历

# 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 flatten(self, root):
        if root == None:
            return None 
        self.flatten(root.left)
        self.flatten(root.right)
        if root.left != None:
            p = root.left
            while p.right != None:
                p = p.right
            p.right = root.right
            root.right = root.left
            root.left = None

1.5给一个初始饮料瓶数,三个空瓶换一瓶,可以赊一瓶,求最后能喝几瓶

def changeWater(cout_0):
    # 喝水的瓶数
    cout_1=0
    if cout_0<2:
        return 0
    while cout_0>2:
        cout_1+=cout_0//3
        cout_0=cout_0//3+cout_0%3
    if cout_0==2:
        cout_1+=1
    return cout_1

1.6岛屿最大面积问题

一个二维的01矩阵,上下左右都是1时算联通,求1组成岛的最大面积。
思路:递归思想,若发现某一位置的数为1,则它周围上下左右都要递归,但是!!!此处递归时需要注意的是,每找到一个位置的数为1时,就要把这个位置的数变为0,否则会进入死循环。

def max_area_of_island(grid):
    if not grid:
        return 0
    l, h = len(grid), len(grid[0])
    
    def dfs(i, j):
        if 0 <= i < l and 0 <= j < h and grid[i][j]:
            grid[i][j] = 0      #每找到一个位置的数为1时,就要把这个位置的数变为0
            return 1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
        return 0
        
     #1)通俗写法
     for i in range(lenr):
            for j in range(lenc):
                if grid[i][j] == 1:
                    count = dfs(i,j)
                    result = max(result,count)
     return result

	#2)精简写法
	result = [dfs(i, j) for i in range(l) for j in range(h) if grid[i][j]]
    return max(result) if result else 0

1.7自己面试手撕的5道算法题

看面经人家两轮技术面手撕两道算法题,到我这…手撕了5道…大概…也许…因为我不是科班出身???
一面(45min):
首先四道算法题,选一道15分钟写完,时间紧迫我选了第一道,给一个列表,求最大连续子序列和问题。
然后笔试题复盘,字符串反转问题改进版,("hello world"变成"world hello"的复杂版,只不过会有些字符干扰,需要判断删除。)
二面(1h):
给一个n数,返回列表,比如n = 13,输出值[1,10,11,12,13,2,3,4,5,6,7,8,9],0<n<50000;
链表反转;
给一个链表,遍历一次,找出倒数第k个节点(这个只说思路,不用手写代码了)

2.剑指offer

2.1 数字中重复的数字

思路1:建立一个同等大小的空数组,原数组的值为新数组的下标,访问一次置1,再次访问直接返回该值。
思路2:若当前值的hash值已经加过1了,则直接返回。

//思路1
int findRepeatNumber(int* nums, int numsSize){
   
    int* arr = calloc(numsSize,sizeof(int)); //函数calloc()会将所分配的内存空间中的每一位都初始化为零

    for (int i=0; i< numsSize; i++){
   
        if (0 == arr[nums[i]]){
   
            arr[nums[i]] = 1;
        }
        else{
   
            return nums[i];
        }
    }
    return -1;
}


//思路2:
int findRepeatNumber(int* nums, int numsSize){
   
    int *hash = (int *)calloc(numsSize, sizeof(int));
    for(int i = 0; i < numsSize; i++){
   
        if(hash[nums[i]] == 1){
   
            return nums[i];
        } else {
   
            hash[nums[i]]++;
        }
    }
    return -1;
}

2.1 二维数组中的查找

def Find(target, array):       # array 二维列表
    if array == [[]]:
        return False
    m = len(array)  # m行n列
    n = len(array[0])
    i = 0
    j = n 
  • 10
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值