剑指offer刷题bi'j

# 二维数组中的查找
# 读取一个矩阵数组和一个数
# 用raw_input读取string, eval转换为数字
L=list(eval(raw_input()))
array=L[1]
target=L[0]

# 字符串替换
# 将空格替换为字符
pat=re.compile(' ')
s=pat.sub('%20', s)

# 从尾到头打印链表
# 定义链表节点
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        stack=[]
        while listNode:
            # list从头插入
            stack.insert(0, listNode.val)
            listNode=listNode.next
        # list反转两种方法
        # stack.reverse()
        # stack[::-1]
        return stack

#数组排序
rotateArray=sorted(rotateArray, reverse=True) #从大到小

#二进制中1的个数
#利用1的二进制左移
def NumberOf1(self, n):
        count=0
        flag=1
        for i in range(32):
            if n&flag:
                count+=1
            flag=flag<<1
        return count

#顺时针打印矩阵
#矩阵的逆时针旋转
matrix[:]=map(list, zip(*matrix)[::-1])
#一行代码搞定矩阵顺时针逆时针旋转
>>> [print(i) for i in a]
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[None, None, None]
>>> [print(i) for i in list(zip(*a))[::-1]]
(3, 6, 9)
(2, 5, 8)
(1, 4, 7)
[None, None, None]
>>> [print(i) for i in list(map(lambda x:x[::-1], list(zip(*a))))]
(7, 4, 1)
(8, 5, 2)
(9, 6, 3)
[None, None, None]

#复杂链表的复制
#id取地址
nodeDict[id(cur)]=i

#字符串的字典序排列
import itertools
sorted(list(set(map(''.join, itertools.permutations(ss)))))

#最小的K个数
#heapq小顶堆,维护最大的看k个数
import heapq
res = []
heapq.heapify(res)
for i in range(k):
    heapq.heappush(res, -1*tinput[i])
for j in tinput[k:]:
    heapq.heappushpop(res, -j)
return sorted([-i for i in res])

#数组排成最小的数
nmb = lambda x, y: int(str(x)+str(y)) - int(str(y)+str(x)) 
tmp = sorted(numbers, cmp=nmb)
return ''.join(str(i) for i in tmp)

#第一个只出现一次的字符
#字母哈希
haxi = [0]*256
for i in range(len(s)):
    haxi[ord(s[i])] += 1
for j in range(len(s)):
    if haxi[ord(s[j])] == 1:
        return j
return -1

#数组中只出现一次的数字
#留意异或操作与判断bit1的方法
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        if not array or len(array)<=2:
            return []
        tmp = self.ExOr(array)
        i = 0
        while tmp and i<=32:
            tmp = tmp>>1
            i+=1
        res1 = []
        res2 = []
        for each in array:
            if self.isBit1(each, i):
                res1.append(each)
            else:
                res2.append(each)
        first = self.ExOr(res1)
        second =self.ExOr(res2)
        return [first, second]
                
        
    
    def ExOr(self, array):
        res = 0
        for i in array:
            res = res ^ i
        return res
    
    def isBit1(self, n, i):
        tmp = n>>(i-1)
        return tmp&1

#不用加减乘除做加法
int Add(int num1, int num2)
{
    while (num2!=0) {
        int temp = num1^num2;
        num2 = (num1&num2)<<1;
        num1 = temp;
    }
    return num1;
}

#数据流的中位数
#C++优先队列
class Solution {
    priority_queue<int, vector<int>, less<int> > p;
    priority_queue<int, vector<int>, greater<int> > q;
     
public:
    void Insert(int num){
        if(p.empty() || num <= p.top()) p.push(num);
        else q.push(num);
        if(p.size() == q.size() + 2) q.push(p.top()), p.pop();
        if(p.size() + 1 == q.size()) p.push(q.top()), q.pop();
    }
    double GetMedian(){ 
      return p.size() == q.size() ? (p.top() + q.top()) / 2.0 : p.top();
    }
};

#滑动窗口的最大值
#双端队列的运用
class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> res;
        deque<int> s;
        for(unsigned int i=0;i<num.size();++i){
            while(s.size() && num[s.back()]<=num[i])//从后面依次弹出队列中比当前num值小的元素,同时也能保证队列首元素为当前窗口最大值下标
                s.pop_back();
            while(s.size() && i-s.front()+1>size)//当当前窗口移出队首元素所在的位置,即队首元素坐标对应的num不在窗口中,需要弹出
                s.pop_front();
            s.push_back(i);//把每次滑动的num下标加入队列
            if(size&&i+1>=size)//当滑动窗口首地址i大于等于size时才开始写入窗口最大值
                res.push_back(num[s.front()]);
        }
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值