日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网剑指offer编程实践31-40题

發布時間:2023/12/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网剑指offer编程实践31-40题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

31、 整數中1出現的次數(從1到n整數中1出現的次數)

求出1~13的整數中1出現的次數,并算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對于后面問題他就沒轍了。ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。

解答:

方法:

設定整數點(如1、10、100等等)作為位置點i(對應n的各位、十位、百位等等),分別對每個數位上有多少包含1的點進行分析

1、根據設定的整數位置,對n進行分割,分為兩部分,高位n/i,低位n%i

2、當i表示百位,且百位對應的數>=2,如n=31456,i=100,則a=314,b=56,此時百位為1的次數有a/10+1=32(最高兩位0~31),每一次都包含100個連續的點,即共有(a%10+1)*100個點的百位為1

3、當i表示百位,且百位對應的數為1,如n=31156,i=100,則a=311,b=56,此時百位對應的就是1,則共有a%10(最高兩位0-30)次是包含100個連續點,當最高兩位為31(即a=311),本次只對應局部點00~56,共b+1次,所有點加起來共有(a%10*100)+(b+1),這些點百位對應為1

4、當i表示百位,且百位對應的數為0,如n=31056,i=100,則a=310,b=56,此時百位為1的次數有a/10=31(最高兩位0~30)

5、綜合以上三種情況,當百位對應0或>=2時,有(a+8)/10次包含所有100個點,還有當百位為1(a%10==1),需要增加局部點b+1

6、之所以補8,是因為當百位為0,則a/10==(a+8)/10,當百位>=2,補8會產生進位位,效果等同于(a/10+1)

# -*- coding:utf-8 -*- class Solution:def NumberOf1Between1AndN_Solution(self, n):# write code herei = 1count = 0while i <= n:a = n / ib = n % icount = count + (a+8)/10*i + (a%10==1)*(b+1)i *= 10return count

32、把數組排成最小的數

輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字為321323。

解答:

方法:比較字符串s1和s2大小時,即比較s1+s2和s2+s1的大小,小的放在前面,比較某一位的字符時,需要將這個位置和其后面所有位置的字符串進行比較。時間復雜度為O(n^2),注意兩點:1、數組為空時要返回‘’;2、數組中全為0時,返回的是0,而不是00000.

# -*- coding:utf-8 -*- class Solution:def PrintMinNumber(self, numbers):# write code hereif numbers == []:return ''for i in range(len(numbers)):for j in range(i+1,len(numbers)):tmp0 = int(str(numbers[i]) + str(numbers[j]))tmp1 = int(str(numbers[j]) + str(numbers[i]))if tmp0 > tmp1:numbers[i],numbers[j] = numbers[j],numbers[i]res = ''for i in numbers:res += str(i)if int(res) == 0:return 0else:return res

33、丑數

把只包含質因子2、3和5的數稱作丑數(Ugly Number)。例如6、8都是丑數,但14不是,因為它包含質因子7。 習慣上我們把1當做是第一個丑數。求按從小到大的順序的第N個丑數。

解答:

方法1:暴力求解,任何丑數p,2p,3p,5p結果仍是偶數,1是最小的丑數,從1開始,將12,13,15比較,得到的最小丑數2,將得到的丑數2也同樣2,3,*5,比較最小的數

# -*- coding:utf-8 -*- class Solution:def GetUglyNumber_Solution(self, index):# write code hereif index < 7:return indexres = [0] * indexres[0] = 1tmp2 = 0tmp3 = 0tmp5 = 0for i in range(1,index):res[i] = min(res[tmp2]*2,res[tmp3]*3,res[tmp5]*5)if res[i] == res[tmp2]*2:tmp2 += 1if res[i] == res[tmp3]*3:tmp3 += 1if res[i] == res[tmp5]*5:tmp5 += 1return res[-1]

34、第一個只出現一次的字符

在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符,并返回它的位置, 如果沒有則返回 -1(需要區分大小寫).

解答:

# -*- coding:utf-8 -*- class Solution:def FirstNotRepeatingChar(self, s):# write code hereres_dict = {}for i in range(len(s)):if s[i] not in res_dict:res_dict[s[i]] = 0res_dict[s[i]] += 1for i in range(len(s)):if res_dict[s[i]] == 1:return ireturn -1

35、數組中的逆序對

在數組中的兩個數字,如果前面一個數字大于后面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。并將P對1000000007取模的結果輸出。 即輸出P%1000000007

解答:

方法:歸并排序,在合并時,當前面的數組值array[i]大于后面數組值array[j]時,則前面

數組array[i]~array[mid]都是大于array[j]的,count += mid+1 - i

# -*- coding:utf-8 -*- class Solution:def __init__(self):self.count = 0def InversePairs(self, data):if len(data) == 0:return 0# write code hereself.MergeSort(data,0,len(data)-1)return self.count%1000000007def MergeSort(self,array,low,high):if low < high:mid = (low + high) >> 1self.MergeSort(array,low,mid)self.MergeSort(array,mid+1,high)self.count += self.MergeArray(array,low,mid,high) ?def MergeArray(self,array,low,mid,high):i = lowj = mid + 1tmp = []count = 0while i <= mid and j <= high:if array[i] < array[j]:tmp.append(array[i])i += 1else:tmp.append(array[j])j += 1count += mid - i + 1while i <= mid:tmp.append(array[i])i += 1while j <= high:tmp.append(array[j])j += 1for k in range(len(tmp)):array[low + k] = tmp[k]return count

36、兩個鏈表的第一個公共結點

輸入兩個鏈表,找出它們的第一個公共結點。

解答:

方法1:

長度相同有公共結點,第一次就遍歷到;沒有公共結點,走到尾部NULL相遇,返回NULL? 長度不同有公共結點,第一遍差值就出來了,第二遍一起到公共結點;沒有公共,一起到結尾NULL。

方法2:

遍歷兩個鏈表,如果鏈表長度相同,找到第一個相同的結點;不相同時,先將長的鏈表移動到和短的鏈表相同長度的位置,然后找到第一個相同的結點

# -*- coding:utf-8 -*- # class ListNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.next = None class Solution:def FindFirstCommonNode(self, pHead1, pHead2):# write code herep1 = pHead1p2 = pHead2while p1 != p2:if not p1:p1 = pHead2else:p1 = p1.nextif not p2:p2 = pHead1else:p2 = p2.nextreturn p1def FindFirstCommonNode(self, pHead1, pHead2):# write code heresum1 = self.get_length(pHead1)sum2 = self.get_length(pHead2)if sum1 > sum2:pHead1 = self.get_equal(pHead1,sum1-sum2)else:pHead2 = self.get_equal(pHead2,sum2-sum1)while pHead1 != pHead2:pHead1 = pHead1.nextpHead2 = pHead2.nextreturn pHead1def get_equal(self,pHead,s):while s > 0:pHead = pHead.nexts -= 1return pHeaddef get_length(self,pHead):summ = 0while pHead:pHead = pHead.nextsumm += 1return summ

37、數字在排序數組中出現的次數

統計一個數字在排序數組中出現的次數

解答:

方法1:

排序數組是升序排列,且數組中的數都是整數,則可以使用tmp0 = k – 0.5 和tmp1 = k + 0.5兩個數,這兩個數在數組中都沒有,但可以找到第一個大于tmp0和tmp1的數的index,相減就是最后k出現的次數

方法2:

如果數組中的數不是整數,則利用二分法找到k值的第一次出現的index和最后一次出現的index;注意考慮沒有k值的情況。

# -*- coding:utf-8 -*- class Solution:def GetNumberOfK(self, data, k):tmp0 = k - 0.5tmp1 = k + 0.5count = self.get_index(data,tmp1) - self.get_index(data,tmp0)return count ?def get_index(self,data,k):begin = 0end = len(data) - 1while begin <= end:mid = (begin + end) >> 1if data[mid] < k:begin = mid + 1elif data[mid] > k :end = mid - 1return beginclass Solution:def GetNumberOfK(self, data, k):tmp0 = self.get_first(data,k,0,len(data)-1)tmp1 = self.get_last(data, k, 0, len(data) - 1)if tmp0 != -1 and tmp1 != -1:return tmp1 - tmp0 + 1return 0 ? ?def get_first(self,data,k,begin,end):if begin > end:return -1mid = (begin + end) >> 1if data[mid] > k:return self.get_first(data,k,begin,mid-1)elif data[mid] < k:return self.get_first(data,k,mid+1,end)elif mid - 1 >= begin and data[mid-1] == k:return self.get_first(data,k,begin,mid-1)else:return mid ?def get_last(self,data,k,begin,end):while begin <= end:mid = (begin + end) >> 1if data[mid] > k:end = mid - 1elif data[mid] < k:begin = mid + 1elif mid + 1 <= end and data[mid+1] == k:begin = mid + 1else:return midreturn -1 ?

?

38、 二叉樹的深度

輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。

解答:

方法1:

遞歸,遞歸實際也是深度優先的思想(DFS),時間復雜度為O(lgN),但是空間復雜度最壞為O(N),當二叉樹退化為鏈表的時候。

方法2:

非遞歸,廣度優先遍歷BFS,時間復雜度O(N);利用兩個輔助值sum_count和count;sum_count記錄每層的結點個數,當count == sum_count時說明一層的結點都已經遍歷完畢,depth+1

# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:def TreeDepth(self, pRoot):if not pRoot:return 0left = int(self.TreeDepth(pRoot.left))right = int(self.TreeDepth(pRoot.right))return max(left,right)+1def TreeDepth(self, pRoot):# write code hereif not pRoot:return 0stack = []stack.append(pRoot)sum_count = 1count = 0depth = 0while stack:node = stack.pop(0)count += 1if node.left:stack.append(node.left)if node.right:stack.append(node.right)if count == sum_count:count = 0sum_count = len(stack)depth += 1return depth

39、平衡二叉樹

輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。

解答:

方法1:遞歸法

有了求二叉樹的深度的經驗之后,很容易想到一個思路:遍歷每個結點的時候,得到它的左右結點的深度。如果每個結點的左右二叉樹的深度相差都不超過1,就是平衡二叉樹。

但是這個方法每個結點都被重復遍歷,效率不高

方法2:自底向上

如果我們用后序遍歷的方式遍歷二叉樹的每一個結點,在遍歷到一個結點之前我們就已經遍歷了它的左右子樹。只要在遍歷每個結點的時候幾下它的深度,就可以一次遍歷判斷每個結點是不是平衡二叉樹。

# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:def IsBalanced_Solution(self, pRoot):depth = self.get_depth(pRoot)if depth == -1:return Falsereturn Truedef get_depth(self,pRoot):if not pRoot:return 0left = self.get_depth(pRoot.left)if left == -1:return -1right = self.get_depth(pRoot.right)if right == -1:return -1if abs(left-right) <= 1:return max(left,right) + 1else:return -1def IsBalanced_Solution(self, pRoot):# write code hereif not pRoot:return Trueleft = self.get_depth(pRoot.left)right = self.get_depth(pRoot.right)return abs(left - right) <= 1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right) ?def get_depth(self, pRoot):if not pRoot:return 0return max(self.get_depth(pRoot.left), self.get_depth(pRoot.right)) + 1

40、 數組中只出現一次的數字

一個整型數組里除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。

解答:

方法:

1、考慮數組中只有一個數只出現一次,則將所有數字異或就可以得到這個數。

2、兩個數不一樣,則異或的結果至少有一位為1,我們找到第一個為1的位置,記作n;

找到數字k第一個為1的位

3、根據第n為是否為1的標準可以將數組分為2個部分,這兩個只出現一次的數就分別在這兩個部分中,在通過異或即可得到結果

# -*- coding:utf-8 -*- class Solution:# 返回[a,b] 其中ab是出現一次的兩個數字def FindNumsAppearOnce(self, array):# write code hereres = 0for i in array:res ^= iindex = self.get_index(res)num0 = num1 = 0for i in array:if self.get_sep(i,index) == 0:num0 ^= ielse:num1 ^= ireturn num0,num1 ?def get_index(self,k):index = 0while k & 1 == 0:k = k >> 1index += 1return indexdef get_sep(self,k,index):k = k >> indexreturn k & 1

總結

以上是生活随笔為你收集整理的牛客网剑指offer编程实践31-40题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。