顺时针打印矩阵+矩阵中是否存在某路径+Google KickStart8.24B题

每天积累一点点,相信校招结束时会很棒

顺时针打印矩阵

我发现牛客网上有这道原题哎
https://www.nowcoder.com/questionTerminal/9b4c81a02cd34f76be2659fa0d54342a

看到一个大神的思路实在是惊艳到我了

class Solution:
    def printMatrix(self, matrix):
        result = []
        while(matrix):
            result+=matrix.pop(0)
            if not matrix or not matrix[0]:
                break
            matrix = self.turn(matrix)
        return result
    def turn(self,matrix):
        num_r = len(matrix)
        num_c = len(matrix[0])
        newmat = []
        for i in range(num_c):
            newmat2 = []
            for j in range(num_r):
                    newmat2.append(matrix[j][i])
            newmat.append(newmat2)
        newmat.reverse()
        return newmat

附赠一个更好理解的翻转矩阵函数

def turn(self, matrix):
        # 逆时针旋转函数
        col = len(matrix[0])
        newmat = []
        for i in range(col, 0, -1):
            newmat.append([x[i-1] for x in matrix])
        return newmat

思路解析:
比如我要打印
1,2,3,
4,5,6
7,8,9
10,11,12
弹出第一行以后,剩下
4,5,6
7,8,9
10,11,12
此时调用翻转函数turn(),矩阵翻转成
6,9,12
5,8,11
4,7,10
再弹出第一行 6,9 ,12,剩下
5,8,11
4,7,10
再翻转
11,10
8,7
5,4
弹出11,10,剩下
8,7,
5,4
翻转为
7,4
8,5
弹出7,4
剩下8,5
翻转为
5,
8
弹出5
剩下8
弹出8
结束while

我个人的解法,面试时初步的想法完善而成:

def custom_print(matrix):
    row=len(matrix)
    print("row  number is",row)
    col=len(matrix[0])
    print("col number is",col)
    totalcnt=row*col#总共元素数量
    currentcnt=0
    rowstart=0
    rowend=row
    colstart=0
    colend=col
    #向右打印
    while 1:
        for i in range(colstart,colend):
            print("right")
            print(matrix[rowstart][i])
        currentcnt+=colend-colstart
        rowstart+=1
        if currentcnt==totalcnt:
            print("bingo1!")
            break

        #向下打印
        for i in range(rowstart,rowend):
            print("down")
            print(matrix[i][colend-1])
        currentcnt+=rowend-rowstart
        colend-=1
        if currentcnt == totalcnt:
            print("bingo2!")
            break
        #向左打印
        for i in range(colend-1,colstart-1,-1):
            print("left")
            print(matrix[rowend-1][i])
        currentcnt+=colend-colstart
        rowend-=1
        if currentcnt == totalcnt:
            print("bingo3!")
            break
        #向上打印
        for i in range(rowend-1,rowstart-1,-1):
            print("up")
            print(matrix[i][colstart])
        currentcnt+=rowend-rowstart
        colstart+=1
        if currentcnt == totalcnt:
            print("bingo4!")
            break

时间复杂度我觉得是O(n),因为相当于把每个元素都遍历一次
面试时我的思路竟然是对的哎!错误的地方在于
1:我定义了一个direction变量,用来判断当前的方向,方向改变时要对direction重新赋值。比如往右遍历完时,要让direction=’down’ 完全没有必要没有实际作用好嘛!
2.while是永真循环,判断循环是否结束在每一个for循环里,而非while (currentcnt小于totalcnt)
3.倒序遍历一维链表语法错误,在此复习一下正确的语法:
“`python
l=[10,11,12]
for i in range(2,-1,-1):
print(l[i])

12
11
10

注意与上者的区别
l=[10,11,12]
for i in range(2,0,-1):
print(l[i])
12
11

python内存管理机制

https://www.cnblogs.com/vamei/p/3232088.html 总结的太棒了!

矩阵中是否存在某路径

链接:https://www.nowcoder.com/questionTerminal/c61c6999eecb4b8f88a98f66b273a3cc
来源:牛客网

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串”bcced”的路径,但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

我的思路:
DFS,深度搜索,用递归完成

代码: 我要自己写一遍,不是为了拿到什么OFFER,只是我好奇到底我的解法对不对,要亲自AC100%才相信

word='abe'
row=4
col=3
board='abcdefghijkl'
class Solution:
    def hasPath(self,board,row,col,targetstr):
        self.col=col
        self.row = row
        boardmat=[list(board[col*i:col*i+col]) for i in range(row)]
        #print(boardmat)
        self.matchedflag = False
        for i in range(row):
            for j in range(col):
                if boardmat[i][j]==targetstr[0]:
                    #print("this time boardmat[i][j] is",boardmat[i][j],"targetstr[0]",targetstr[0])
                    self.search(boardmat,targetstr[1:],[(i,j)],i,j)
                    #print("match is",match)
                    if self.matchedflag==True:
                        return True

        return  False

    def search(self,boardmat,targetstr,pathdict,i,j):
        #print("now visit",boardmat[i][j],"AND targetstr is",targetstr)
        if len(targetstr)==0:#当要匹配的字符串为空串时
            #print(dict)
            self.matchedflag=True
            return   #递归的出口,相当于return了None#递归函数本来返回的也是None
            #print("test")
        if j!=0 and (i,j-1) not in pathdict and boardmat[i][j-1]==targetstr[0]:#检查当前字符左边的字符,是不是匹配targetstr剩余部分的第一个字符
            #如果当前列不是最左边的列  并且 当前字符左边的字符没有被访问过  并且  当前字符左边的字符与targetstr剩余部分的第一个字符匹配
            self.search(boardmat, targetstr[1:], pathdict + [(i, j - 1)], i, j - 1)
        if i!=0 and (i-1,j) not in pathdict and boardmat[i-1][j]==targetstr[0]:#检查当字符上边的字符
            self.search(boardmat,targetstr[1:],pathdict+[(i-1,j)],i-1,j)
        if j!=self.col-1 and  (i,j+1) not in pathdict and boardmat[i][j+1] == targetstr[0]:#检查当前字符右边的字符
            self.search(boardmat,targetstr[1:],pathdict+[(i,j+1)],i,j+1)
        if i!=self.row-1 and (i+1,j) not in pathdict and boardmat[i+1][j]==targetstr[0]:#检查当前字符下边的字符
            self.search(boardmat,targetstr[1:],pathdict+[(i+1,j)],i+1,j)

sol=Solution()
result=sol.hasPath(board,4,3,word)
print(result)

求有序数组中最小值

京东面试题:
给定一个排好序的数组 找到元素a, b 使||a| -|b||值最小 返回ab的index和最小值
面试官解题思路:
先把所有元素求绝对值,然后一个指针指头,一个指针指尾,向中间遍历,时间复杂度O(n/2)
代码如下

def func1(nums):
    absnums=list(map(abs,nums))
    minimum=float("inf")
    head=0
    tail=len(absnums)-1
    while head<tail:
        headmin=abs(absnums[head]-absnums[head+1])
        tailmin=abs(absnums[tail]-absnums[tail-1])
        if headmin<tailmin and headmin<minimum:
            minimum=headmin
        if tailmin<headmin and tailmin<minimum:
            minimum=tailmin
        head=head+1
        tail=tail-1
    return  minimum

我觉得这不对吧,因为面试官的前提相邻两个元素产生最小值就不对呀!比如对于输入:
func1([-9,-7,1,10,99])的结果是2
但应该是1,因为排序好后1,7,9,10,99,最小值在9和10中间,差是1
代码实现:

#给定一个排好序的数组 找到元素a, b 使||a| -|b||值最小 返回ab的index和最小值
def func1(nums):
    absnums=list(map(abs,nums))
    minimum=float("inf")
    indexlist=[i for i in range(len(absnums))]
    index_absval_list=list(zip(absnums,indexlist))
    print (index_absval_list)
    #print(dict(index_absval_list))
    index_absval_list.sort(key=lambda tp:tp[0])
    print("After sort",index_absval_list)
    for i in range(0,len(index_absval_list)-1):
        currentmin=index_absval_list[i+1][0]-index_absval_list[i][0]
        if currentmin<minimum:
            minimum=currentmin
    return  minimum

输出

res=func1([-9,-7,1,10,99])
[(9, 0), (7, 1), (1, 2), (10, 3), (99, 4)]
After sort [(1, 2), (7, 1), (9, 0), (10, 3), (99, 4)]
res
Out[3]: 1

时间复杂度分析:排序是O(nlogn), 遍历一遍是O(n),相加得O(n(logn+1))

Google KickStart8.24B题

第一次考kickstart,不会读取文件输入,好耽误事
马后炮版个人答案,可惜没机会提交看对不对了,请大佬们赐教


def CalComplainCnt(numdict,numAppearCnt):#计算抱怨次数
    complainCnt=0
    for index in range(0,len(numdict)):
        curdigitmode=int(numAppearCnt[index][0])
        curdigitlist=numdict[index]
        if len(curdigitlist)==2:
            if curdigitmode==0:#如果当前数位的众数是0
                complainCnt+=curdigitlist[1][1]
            if curdigitmode==1:#如果当前数位的众数是1
                complainCnt+=curdigitlist[0][1]
        if len(curdigitlist)==1:
            if curdigitmode!=curdigitlist[0][0]:#如果当前数位的众数是0
                complainCnt+=curdigitlist[0][1]

    print("抱怨次数",complainCnt)
    return  complainCnt

def get_mode(arr):#求众数
    mode = [];
    arr_appear = dict((a, arr.count(a)) for a in arr);  # 统计各个元素出现的次数
    if max(arr_appear.values()) == 1:  # 如果最大的出现为1
        mode.append(list(arr_appear.keys())[0])
    else:
        maximum=-1
        for k, v in arr_appear.items():  # 否则,出现次数最大的数字,就是众数
            if v == max(arr_appear.values())and max(arr_appear.values())>maximum:
                maximum=max(arr_appear.values())
                mode.append(k);
    return mode;


def calresult(frs,forbid):
    length=len(frs[0])
    reverse=[]#print(reverse)#每一个子数组是朋友喜好某数位的一列
    for i in range(0,length):
        temp=[int(x[i]) for x in frs]
        reverse.append(temp)


    #求众数
    numAppearCnt=[]
    numdict=[]
    for digitlist in reverse:
        arr_appear = sorted(dict((a, digitlist.count(a)) for a in digitlist).items(),key=lambda k:k[0]);  # 统计各个元素出现的次数
        numdict.append(arr_appear)
        numAppearCnt.append(get_mode(digitlist))

    print("numdict is",numdict)#每一位数0出现了几次,1出现了几次
    print("每一位的众数是",numAppearCnt)

    #计算抱怨次数
    complainCnt=CalComplainCnt(numdict,numAppearCnt)

    #print (numAppearCnt)['1', '0', '0', '0']
    bestchoice=''.join([str(x[0]) for x in numAppearCnt])

    cha = []
    for i in range(0, len(numdict)):
        if len(numdict[i]) == 2:#如果既有0也有1
            cha.append([abs(numdict[i][0][1] - numdict[i][1][1]),i])
        else:#如果只有0或者只有1
            cha.append([numdict[i][0][1],i])
    cha=sorted(cha, key=lambda k: k[0])

    print("没进while时候的最佳选择",bestchoice)

    while(bestchoice in forbid and len(cha)>0):#当最佳的选择在禁止名单里的时候
        modifydigit=cha[0][1]
        print(cha)
        numAppearCnt[modifydigit][0]=1-numAppearCnt[modifydigit][0]#改一位,对0或1区反
        bestchoice=''.join([str(x[0]) for x in numAppearCnt])
        complainCnt=CalComplainCnt(numdict,numAppearCnt)
        print("bestchoice is ",bestchoice)
        if bestchoice not in forbid:
            return complainCnt
        else:
            del cha[0]
            numAppearCnt[modifydigit][0]=1-numAppearCnt[modifydigit][0]
    return complainCnt

if __name__ == '__main__':
    file=open('B-small-attempt0.in')
    #file=open('B2.in')
    lines=file.readlines()

    TestCases=int(lines[0].strip())
    curCase=0
    start=1
    while(curCase<TestCases):
        N,M,P=list(map(int,lines[start].strip().split()))
        start=start+1
        friends=[]
        forbid=[]
        rowcnt=0
        while rowcnt<N:
            friends.append(lines[start+rowcnt].strip())
            rowcnt+=1

        start += N
        print("After N, Now the start is",start)

        rowcnt=0
        while rowcnt<M:
            forbid.append(lines[start + rowcnt].strip())
            rowcnt += 1
        start+=M
        print("After M, Now the start is", start)
        res = calresult(friends, forbid)
        print("Case #",curCase,":",res)
        curCase+=1









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值