剑指offer|解析和答案(C++/Python) (一)

剑指offer|解析和答案(C++/Python) (一)

参考剑指offer(第二版),这里做一个学习汇总,包括解析及代码。代码均在牛客网进行验证(摘自自己的牛客网笔记)。

整个剑指offer解析链接:
剑指offer|解析和答案(C++/Python) (一).
剑指offer|解析和答案(C++/Python) (二).
剑指offer|解析和答案(C++/Python) (三).
剑指offer|解析和答案(C++/Python) (四).
剑指offer|解析和答案(C++/Python) (五)上.
剑指offer|解析和答案(C++/Python) (五)下.
剑指offer|解析和答案(C++/Python) (六).

习题

面试需要的基础知识
1.数组中重复的数字
2.二维数组中的查找
3.替换空格
4.从头到尾打印链表
5.重建二叉树
6.二叉树的下一个节点
7.用两个栈实现队列
8.斐波那契数列
9.旋转数组的最小数字
10.矩阵中的路径
11.机器人的运动范围
12.剪绳子
13.二进制中1的个数
14.跳台阶

1.数组中重复的数字

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路:
1.使用哈希表。将哈希表初始化为0,然后从头到尾扫描数组的每个数字,每扫到一个数字的时候,可以用O(1)的时间复杂度判断哈希表里面是否包含了该数字。如果有则加1。扫描完后,从头到尾扫描哈希表,只要对应的数值大于1,则有重复的数字,返回true。遍历完没有大于1的,则返回false。
代码:
C++

class Solution {
   
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
   
        vector<int> completeNum;
        for(int i = 0; i < length; ++i){
   
            completeNum.push_back(0);
        }
        for(int i = 0; i < length; ++i){
   
            ++completeNum[numbers[i]];
        }
        for(int i = 0; i < length; ++i){
   
            if(completeNum[i]>1){
   
                *duplication = i;
                return true;
            }
        }
        return false;
    }
};

2.使用哈希表的时间复杂度是O(n),空间复杂度是O(n),还有可以优化的空间。使用数值和ID交换的思路,可以实现空间复杂度是O(1)的算法。
数组数字的范围是0~n-1。如果数组中没有重复的数字,那么当数组排序之后数字i将出现在下标为i的位置,如果数组中有重复的数字,那么必定会出现数字i不仅仅出现在下标为i的位置,还可能出现在下标为m、x…的位置,只要发现下标为m和下标为i的数字相同,则发现有重复的数字,返回ture。
代码:
C++

class Solution {
   
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
   
        for(int i = 0; i < length; ++i){
   
            while(i != numbers[i]){
   
                //判断
                if(numbers[i] == numbers[numbers[i]]){
   
                    //找到重复的数字
                    *duplication = numbers[i];
                    return true;
                }
                //交换顺序
                int temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;
            }
        }
        return false;
    }
};

Python

# -*- coding:utf-8 -*-
class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        for i in range(len(numbers)):
            #对应位置上的元素不相等
            while numbers[i] != i:
                #判断
                if numbers[i] == numbers[numbers[i]]:
                    #找到重复的数字
                    duplication[0] = numbers[i]
                    return True
 
                #交换位置
                temp = numbers[i]
                numbers[i] = numbers[temp]
                numbers[temp] = temp
        #没有找到重复的
        return False

2.二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:
从右上角元素为参考元素,每次和target进行比较。如果target等于参考元素,那么返回true,如果不是进行比较。1.target大于参考元素,则排除该行。2.如果target小于参考元素,则排除该列。一次类推,直到达到边界条件,如果还没有没有找到,则返回false。
C++

class Solution {
   
public:
    bool Find(int target, vector<vector<int> > array) {
   
 
        int cols = array[0].size();
        int rows = array.size();
        if( array.empty()==0 && cols > 0 && rows > 0){
   
        //查找右上角的元素
        int col = cols - 1;
        int row = 0;
        //如果target大于该元素,则排除该行,如果target小于该元素,排除该列
 
        while( col >= 0 && row < rows){
   
            if( target == array[row][col]){
   
                return true;
            }else if( target > array[row][col]){
   
                ++row;
            }else if( target < array[row][col]){
   
                --col;
            }
        }
        }
        return false;
    }
};

Python

class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        cols = len(array[0])
        rows = len(array)
        if cols > 0 and rows > 0:
            col = cols - 1
            row = 0
            while row < rows and col >= 0 :
                if target == array[row][col]:
                    return 1
                elif target < array[row][col]:
                    col = col - 1
                else :
                    row = row +1    
        return 0

3.替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

思路
两个方向
1.正向查找,找到’ ‘就把后面的字符数组后移2位,同时把’ ‘替换为’%20‘。但是这样每找到’ '就后把后面的所以字符数组移动,假设这个字符数组长度为n,时间复杂度为O(n^2)。
2.反向查找,对原字符数组进行“扩容”,计算所有的’ ‘的个数,一个指针指向“扩容”数组的最后一个,一个指针指向“原”数组的最后一个,依次赋值移动。
C++

class Solution{
   
public:
	//length 为字符数组str的总容量
	void replaceSpace(char*str,int length) {
   
		//特殊情况判断
	        if( str == nullptr||length <= 0){
   
	        	return;
	        }
		 //记录空格数目
	        int originalLength = 0;//计算原字符串实际长度
	        int numberOfBlank = 0;//记录空格数目
	        int i = 0;
	        while(str[i] !='\0'){
   
	            ++originalLength;
	            if( str[i] ==' '){
   
	                ++numberOfBlank;
	            }
	            ++i;
	        }
	        //判断是否超出容量
	        int newLength = originalLength + 2*numberOfBlank;
	        if(newLength > length){
   
	            return;
	        }
	        int indexOfOriginal = originalLength;
	        int indexOfNew = newLength;//倒序排列赋值
	        while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal){
   
	            //注意originalLength是排除'\0'之后的长度,
	            //所以第一次进入循环时:str[originalLength] = '\0'
	            if( str[indexOfOriginal] ==' '){
   
	                str[indexOfNew--] ='0';
	                str[indexOfNew--] ='2';
	                str[indexOfNew--] ='%';
	            }else{
   
	                str[indexOfNew--] = str[indexOfOriginal];
	            }
	            --indexOfOriginal;
        	}
	}
}; 

Python

class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here        
        originalLength = len(s)
        #记录空格数
        i = 0
        numberOfBlank = 0
        while i < originalLength:
            if s[i] == ' ':
                numberOfBlank = numberOfBlank + 1
            i = i + 1
        newLength = originalLength + 2*numberOfBlank 
        indexOriginal = originalLength - 1
        indexNewstr = newLength - 1       
        #python的string类型不允许改变 新建一个string
        new_string = [None for i in range(newLength)]
        while indexOriginal >= 0  :
            if s[indexOriginal] == ' ':
                new_string[indexNewstr] = '0'                
                new_string[indexNewstr - 1] = '2'                
                new_string[indexNewstr - 2] = '%'
                indexNewstr = indexNewstr - 3
            else :
                new_string[indexNewstr] = s[indexOriginal]
                indexNewstr = indexNewstr - 1             
            indexOriginal = indexOriginal -1
        return ''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值