牛客网剑指offer编程实践11-20题
11、二進(jìn)制中1的個(gè)數(shù)
輸入一個(gè)整數(shù),輸出該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。
解答:
方法:
如果一個(gè)整數(shù)不為0,那么這個(gè)整數(shù)至少有一位是1。如果我們把這個(gè)整數(shù)減1,那么原來(lái)處在整數(shù)最右邊的1就會(huì)變?yōu)?,原來(lái)在1后面的所有的0都會(huì)變成1(如果最右邊的1后面還有0的話)。其余所有位將不會(huì)受到影響。
舉個(gè)例子:一個(gè)二進(jìn)制數(shù)1100,從右邊數(shù)起第三位是處于最右邊的一個(gè)1。減去1后,第三位變成0,它后面的兩位0變成了1,而前面的1保持不變,因此得到的結(jié)果是1011.我們發(fā)現(xiàn)減1的結(jié)果是把最右邊的一個(gè)1開(kāi)始的所有位都取反了。這個(gè)時(shí)候如果我們?cè)侔言瓉?lái)的整數(shù)和減去1之后的結(jié)果做與運(yùn)算,從原來(lái)整數(shù)最右邊一個(gè)1那一位開(kāi)始所有位都會(huì)變成0。如1100&1011=1000.也就是說(shuō),把一個(gè)整數(shù)減去1,再和原整數(shù)做與運(yùn)算,會(huì)把該整數(shù)最右邊一個(gè)1變成0.那么一個(gè)整數(shù)的二進(jìn)制有多少個(gè)1,就可以進(jìn)行多少次這樣的操作。
# -*- coding:utf-8 -*- class Solution:def NumberOf1(self, n):# write code hereif n == 0:return 0elif n > 0:tag = 0while n != 0:tag += 1n = n & (n-1)return tagelse:n = 2**32 + ntag = 0while n != 0:tag += 1n = n & (n-1)return tag12、數(shù)值的整數(shù)次方
給定一個(gè)double類型的浮點(diǎn)數(shù)base和int類型的整數(shù)exponent。求base的exponent次方。
解答:
方法:快速冪。
舉例:13表示為二進(jìn)制為1101
10^1101 = 10^000110^010010^1000。
2^13 = 2^8 * 2^4 * 2^1
2^8 = 2^4 * 2^4
2^4 = 2^2 * 2^2
2^2 = 2^1 * 2^1
右移運(yùn)算代替除以2;位與運(yùn)算代替取余,判斷奇數(shù)和偶數(shù)。
# -*- coding:utf-8 -*- class Solution:def Power(self, base, exponent):# write code hereif abs(base) < 1e-15 and exponent < 0:return Falseelif exponent == 0:return 1abs_exponent = abs(exponent)result = 1.0tmp_base = basewhile abs_exponent != 0:if (abs_exponent & 1) == 1:result *= tmp_basetmp_base *= tmp_baseabs_exponent = abs_exponent >> 1if exponent > 0:return resultelse:return 1 / result13、調(diào)整數(shù)組順序使奇數(shù)位于偶數(shù)前面
輸入一個(gè)整數(shù)數(shù)組,實(shí)現(xiàn)一個(gè)函數(shù)來(lái)調(diào)整該數(shù)組中數(shù)字的順序,使得所有的奇數(shù)位于數(shù)組的前半部分,所有的偶數(shù)位于數(shù)組的后半部分,并保證奇數(shù)和奇數(shù),偶數(shù)和偶數(shù)之間的相對(duì)位置不變。
解答:
方法1:以時(shí)間換空間,時(shí)間復(fù)雜度O(n^2),空間復(fù)雜度O(1)。類似冒泡算法,前偶后奇就交換。
方法2:新建兩個(gè)列表,時(shí)間復(fù)雜度O(n),空間復(fù)雜度O(n)
# -*- coding:utf-8 -*- class Solution:def reOrderArray(self, array):# write code heren = len(array)for i in range(n):j = n - 1while j > i:if array[j]&1 == 1 and array[j-1]&1 == 0:array[j-1],array[j] = array[j],array[j-1]j -= 1return arraydef reOrderArray(self, array):# write code heren = len(array)j = 0for i in range(n):if (array[j]&1) == 0:array.append(array[j])del array[j]j += 1return array14、鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)
輸入一個(gè)鏈表,輸出該鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)。
解答:
方法1:設(shè)置兩個(gè)指針pre和last都指向head,last先向后移動(dòng)k個(gè)位置,然后pre和last一直向后移動(dòng)至last為空,pre即為倒數(shù)第k個(gè)結(jié)點(diǎn)。
方法2:將鏈表的結(jié)點(diǎn)append到list中,所求即list的倒數(shù)第k位
注意:count的作用是判斷k的值是否大于鏈表長(zhǎng)度,因?yàn)殒湵頍o(wú)法直接計(jì)算長(zhǎng)度。
# -*- coding:utf-8 -*- # class ListNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.next = None ? class Solution:def FindKthToTail(self, head, k):# write code hereif head is None or k < 1:return Nonepre = headlast = headnum = kcount = 0while last is not None:last = last.nextcount += 1if num < 1:pre = pre.nextnum -= 1if count < k:return Nonereturn predef FindKthToTail(self, head, k):# write code hereif head is None:returnelse:tmp = []while head:tmp.append(head)head = head.nextif k > len(tmp) or k < 1:returnreturn tmp[-k]15、反轉(zhuǎn)鏈表
輸入一個(gè)鏈表,反轉(zhuǎn)鏈表后,輸出新鏈表的表頭。
解答:
方法:利用三個(gè)指針實(shí)現(xiàn),pre,pHead,nex。
1、nex保存pHead.next的結(jié)點(diǎn)信息,保證后面的鏈表信息不會(huì)消失;
2、將pre和pHead反轉(zhuǎn)鏈表,使pHead.next=pre;
3、最后將pre,pHead,nex全部向后移動(dòng)一位。
4、直至pHead為空,則pre為最后一個(gè)結(jié)點(diǎn),記錄了反轉(zhuǎn)鏈表的所有信息,即為所求。
# -*- coding:utf-8 -*- # class ListNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.next = None class Solution:# 返回ListNodedef ReverseList(self, pHead):# write code hereif not pHead or not pHead.next:return pHeadpre = Nonenex = Nonewhile pHead:nex = pHead.nextpHead.next = prepre = pHeadpHead = nexreturn pre16、合并兩個(gè)排序的鏈表
輸入兩個(gè)單調(diào)遞增的鏈表,輸出兩個(gè)鏈表合成后的鏈表,當(dāng)然我們需要合成后的鏈表滿足單調(diào)不減規(guī)則。
解答:
方法1:遞歸方法,遞歸中直接pHead = None,pHead = pHead1即可
方法2:非遞歸方法,比較pHead1.val和pHead2.val,較小的放入pHead。非遞歸中創(chuàng)建鏈表需pHead = ListNode(-1),pHead.next = None,root = PHead。最后返回鏈表是root.next,不加.next會(huì)將開(kāi)始的根節(jié)點(diǎn)val=-1加進(jìn)去。注意空鏈表的情況
# -*- coding:utf-8 -*- # class ListNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.next = None class Solution:# 返回合并后列表def Merge(self, pHead1, pHead2):# write code hereif pHead1 is None:return pHead2elif pHead2 is None:return pHead1if pHead1.val <= pHead2.val:pHead = pHead1pHead.next = self.Merge(pHead1.next, pHead2)else:pHead = pHead2pHead.next = self.Merge(pHead1, pHead2.next)return pHead ?def Merge(self, pHead1, pHead2):# write code hereif pHead1 is None:return pHead2elif pHead2 is None:return pHead1pHead = ListNode(None)root = pHead ? ?#root的作用記錄pHead,不能直接返回pHead,因?yàn)樽詈蟮膒Head只指向最后一個(gè)元素while pHead1 and pHead2:if pHead1.val <= pHead2.val:pHead.next = pHead1pHead1 = pHead1.nextelse:pHead.next = pHead2pHead2 = pHead2.nextpHead = pHead.nextif pHead1:pHead.next = pHead1elif pHead2:pHead.next = pHead2return root.next17、樹(shù)的子結(jié)構(gòu)
輸入兩棵二叉樹(shù)A,B,判斷B是不是A的子結(jié)構(gòu)。(ps:我們約定空樹(shù)不是任意一個(gè)樹(shù)的子結(jié)構(gòu))
解答:
方法:
# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:def HasSubtree(self, pRoot1, pRoot2):# write code hereif not pRoot1 or not pRoot2:return Falsereturn self.is_Subtree(pRoot1,pRoot2) or self.is_Subtree(pRoot1.left,pRoot2) or self.is_Subtree(pRoot1.right,pRoot2)def is_Subtree(self,A,B):if not B:return Trueif not A or A.val != B.val:return Falsereturn self.is_Subtree(A.left,B.left) and self.is_Subtree(A.right,B.right)18、二叉樹(shù)的鏡像
操作給定的二叉樹(shù),將其變換為源二叉樹(shù)的鏡像
解答:
方法1:遞歸方法。將根節(jié)點(diǎn)的左右子樹(shù)交換位置,然后分別進(jìn)行遞歸鏡像函數(shù)。因?yàn)樽笥易訕?shù)包含了其下所有子樹(shù)的信息。
方法2:非遞歸方法。利用棧和隊(duì)列的思想,在python中利用list實(shí)現(xiàn),首先將根節(jié)點(diǎn)append到list中;然后將其pop到一個(gè)新建樹(shù)中,將左右子樹(shù)交換位置;然后分別將交換位置后得到的左右子樹(shù)push壓入list,即insert(0,p.left)。在while len(st)>0的循環(huán)中,st.pop(0)和st.pop()結(jié)果相同,由于根節(jié)點(diǎn)的左右子樹(shù)已經(jīng)交換位置,后面的子樹(shù)交換順序無(wú)所謂了。
# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:# 返回鏡像樹(shù)的根節(jié)點(diǎn)def Mirror(self, root):if not root:return Noneif root:root.left,root.right = root.right,root.leftself.Mirror(root.left)self.Mirror(root.right)def Mirror(self, root):# write code hereif not root:return Nonest = []st.append(root)p = TreeNode(None)while len(st)>0:p = st.pop()p.left,p.right = p.right,p.leftif p.left:st.append(p.left)if p.right:st.append(p.right)?
19、順時(shí)針打印矩陣
輸入一個(gè)矩陣,按照從外向里以順時(shí)針的順序依次打印出每一個(gè)數(shù)字,例如,如果輸入如下4 X 4矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數(shù)字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解答:
方法:# 可以模擬魔方逆時(shí)針旋轉(zhuǎn)的方法,一直做取出第一行的操作
# 例如
# 1 2 3
# 4 5 6
# 7 8 9
# 輸出并刪除第一行后,再進(jìn)行一次逆時(shí)針旋轉(zhuǎn),就變成:
# 6 9
# 5 8
# 4 7
# 繼續(xù)重復(fù)上述操作即可
# -*- coding:utf-8 -*- # 可以模擬魔方逆時(shí)針旋轉(zhuǎn)的方法,一直做取出第一行的操作 # 例如 # 1 2 3 # 4 5 6 # 7 8 9 # 輸出并刪除第一行后,再進(jìn)行一次逆時(shí)針旋轉(zhuǎn),就變成: # 6 9 # 5 8 # 4 7 # 繼續(xù)重復(fù)上述操作即可。 class Solution:# matrix類型為二維列表,需要返回列表def printMatrix(self, matrix):# write code hereresult = []while len(matrix) > 0:result.extend(matrix[0])matrix.pop(0)if matrix:matrix = self.turn(matrix)return result ?def turn(self, matrix):r = len(matrix)c = len(matrix[0])res = []for i in range(c)[::-1]:tmp = []for j in range(r):tmp.append(matrix[j][i])res.append(tmp)return res?
20、包含min函數(shù)的棧
定義棧的數(shù)據(jù)結(jié)構(gòu),請(qǐng)?jiān)谠擃愋椭袑?shí)現(xiàn)一個(gè)能夠得到棧中所含最小元素的min函數(shù)(時(shí)間復(fù)雜度應(yīng)為O(1))。
解答:
方法:利用一個(gè)輔助棧來(lái)存放最小值。
棧 3,4,2,5,1
輔助棧 3,3,2,2,1
每入棧一次,就與輔助棧頂比較大小,如果小就入棧,如果大就入棧當(dāng)前的輔助棧頂;當(dāng)出棧時(shí),輔助棧也要出棧;這種做法可以保證輔助棧頂一定都當(dāng)前棧的最小值
# -*- coding:utf-8 -*- #思路:利用一個(gè)輔助棧來(lái)存放最小值 # ? 棧 3,4,2,5,1 # ? 輔助棧 3,3,2,2,1 #每入棧一次,就與輔助棧頂比較大小,如果小就入棧,如果大就入棧當(dāng)前的輔助棧頂 #當(dāng)出棧時(shí),輔助棧也要出棧 #這種做法可以保證輔助棧頂一定都當(dāng)前棧的最小值 class Solution:def __init__(self):self.stack = []self.min_stack = []def push(self, node):# write code hereself.stack.append(node)if not self.min_stack or self.min_stack[-1] > node:self.min_stack.append(node)def pop(self):# write code hereif self.stack[-1] == self.min_stack[-1]:self.min_stack.pop()self.stack.pop()def top(self):# write code herereturn self.stack[-1]def min(self):# write code herereturn self.min_stack[-1]總結(jié)
以上是生活随笔為你收集整理的牛客网剑指offer编程实践11-20题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 王者荣耀英雄配音台词大全
- 下一篇: 牛客网剑指offer编程实践21-30题