剑指offer总结(一)

替换空格
  • python解法:使用join函数可以将列表转换为字符串
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        result=[]
        for char in s:
            if char==" ":
                result.extend("%20")
            else:
                result.extend(char)
        return ''.join(result)
  • c++解法:逐个替代的方法每次都要移动后续的字符串,比较耗时。所以,先计算更新后的总字符串长度,然后倒序替代
class Solution {
public:
void replaceSpace(char *str,int length) {
        //遍历一边字符串找出空格的数量
        if(str==NULL||length<0)
            return ;
        int i=0;
        int oldnumber=0;//记录以前的长度
        int replacenumber=0;//记录空格的数量
        while(str[i]!='\0')
            {
               oldnumber++;
               if(str[i]==' ')
                   {
                     replacenumber++;
                   }
                  i++; 
            }
        int newlength=oldnumber+replacenumber*2;//插入后的长度
        if(newlength>length)//如果计算后的长度大于总长度就无法插入
            return ;
        int pOldlength=oldnumber; //注意不要减一因为隐藏个‘\0’也要算里
        int pNewlength=newlength;
        while(pOldlength>=0&&pNewlength>pOldlength)//放字符
            {
              if(str[pOldlength]==' ') //碰到空格就替换
                  {
                     str[pNewlength--]='0';
                     str[pNewlength--]='2';
                     str[pNewlength--]='%';

                  }
               else //不是空格就把pOldlength指向的字符装入pNewlength指向的位置
               {
                    str[pNewlength--]=str[pOldlength];

               }
             pOldlength--; //不管是if还是elsr都要把pOldlength前移

           }


}
};
从尾到头打印链表
  • python解法:使用insert插入到列表头部
class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if not listNode:
            return []
        result=[]
        while listNode:
            result.insert(0,listNode.val)
            listNode=listNode.next
        return result`
重建二叉树
  • python递归解法
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if len(pre)==0:
            return None
        if len(pre)==1:
            return TreeNode(pre[0])
        else:
            node=TreeNode(pre[0])
            node.left=self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1],tin[:tin.index(pre[0])])
            node.right=self.reConstructBinaryTree(pre[tin.index(pre[0])+1:],tin[tin.index(pre[0])+1:])
        return node
用两个栈实现队列
  • C++求解:这个题有两种思路,一是在入栈的时候借助辅助栈将入栈内容颠倒,代码如下:
class Solution
{
public:
    void push(int node) {
        while(!stack1.empty()){
            int temp=stack1.top();
            stack2.push(temp);
            stack1.pop();
        }
        stack1.push(node);
        while(!stack2.empty()){
            int temp=stack2.top();
            stack1.push(temp);
            stack2.pop();
        }
    }

    int pop() {

            int a =stack1.top();
            stack1.pop();
            return a;

    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
  • 二是在弹出的时候将内容先放到辅助栈,从辅助栈中弹出,在连续弹出的情况下这种方法高效一些
class Solution
{
public:
    void push(int node) {
       stack1.push(node);
    }

    int pop() {
        int a;
        if(stack2.empty()){
            while(!stack1.empty()){
                a=stack1.top();
                stack2.push(a);
                stack1.pop();
            }
        }
        a=stack2.top();
        stack2.pop();
        return a;

    }
private:
    stack<int> stack1;
    stack<int> stack2;
};
旋转数组的最小值
  • python求解:O(n)解法:从左向右遍历一次,遇到右边的数比左边的小即为最小值
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        for i in range(len(rotateArray)-1):
            if rotateArray[i+1]<rotateArray[i]:
                return rotateArray[i+1]
        return rotateArray[0]
  • 二分法,时间复杂度O( log2n) l o g 2 n )
class Solution:
    def minNumberInRotateArray(self, array):
        # write code here
        if len(array) == 0:
            return 0;
        left = 0;
        right = len(array) - 1;
        middle = -1;
        while array[left]>=array[right]:
            if right-left==1:
                middle = right;
                break;

            middle = left + (right - left) / 2
            if array[middle] >= array[left]: 
                left = middle;

            if array[middle] <= array[right]: 
                right = middle;

        return array[middle];
斐波那契数列
  • python解法:动态规划
class Solution:
    def Fibonacci(self, n):
        # write code here
        if n==0:
            return 0
        dp=[0]*(n+1)
        dp[0]=0
        dp[1]=1
        for i in range(2,n+1):
            dp[i]=dp[i-1]+dp[i-2]
        return dp[n]
跳台阶
  • python解法:与斐波那契数列一模一样
class Solution:
    def jumpFloor(self, number):
        # write code here
        if number==0:
            return 0
        dp=[0]*(number+1)
        dp[0]=1
        dp[1]=1

        for i in range(2,number+1):
            dp[i]=dp[i-1]+dp[i-2]
        return dp[number]
变态跳台阶
  • python解法:用与上面类似的方法做会超时,换种思路,每个台阶都有可能跳上去,也有可能不跳上去,所以是 2n1 2 n − 1 种可能
class Solution:
    def jumpFloorII(self, number):
        # write code here
        if number==0:
            return 0
        if number==1:
            return 1
        if number==2:
            return 2
        dp=[0]*(number+1)
        dp[0]=1
        dp[1]=1
        for i in range(2,number+1):
            dp[i]=2*dp[i-1]
        return dp[number]
矩形覆盖
  • 这个问题跟上面的问题是一样的,只是不容易想到。
    PGJH78.png
  • 如上图所示,最终剩一个2x1的或者一个2x2的方块,所以递推方程与上面一样
二进制中1的个数
  • 按位与,左移
class Solution:
    def NumberOf1(self, n):
        # write code here
        count = 0
        for i in range(32):
            count +=  (n >> i)&1
        return count
调整数组使得奇数位于偶数之前
  • 碰到奇数就向前移动,下面的方法属于插入法
class Solution:
    def reOrderArray(self, array):
        # write code here
        for i in range(1,len(array)):
            k=i
            while k:
                if array[k]%2 and array[k-1]%2==0:
                    array[k],array[k-1]=array[k-1],array[k]
                    k-=1
                else:
                    break
        return array
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值