leetcode探索日志(两数之和+整数反转+回文数)

这篇博客记录了作者在刷LeetCode的第一天遇到的三道题目:两数之和、整数反转和回文数。对于两数之和,初级版采用两层循环,高级版利用哈希表降低时间复杂度。整数反转需要考虑溢出问题。回文数的初级版是整数反转的延伸,高级版则采取巧妙的数学方法避免转换为字符串。文章详细介绍了C++和Java的解题思路及注意事项。
摘要由CSDN通过智能技术生成

刷leetcode第一天!

第一道题目:两数之和

 

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

初级版:

两层循环,时间复杂度为0(n²),找到即返回,这种情况下没有考虑到一个数组里面存在两对答案的可能。

知识点:

C++

Vector类(push_back与pop_back比较常用)

注意vector中size()与opacity()的不同。size是当前向量的长度,opacity指容量,当当前长度大于容量时,会自动扩容,应该要尽量避免这种情况,指定足够的容量或者动态。

读取可以通过下标读取,也可通过迭代器。当vector尚为赋值时,无法通过下标读取。注:不可通过nums+i这种数组方式读取!vector的内存分配不在一起,不像数组!

特别注意vector的传值。

1、形参传值

vector<int> nums(10,0);

void test( vector<int> elements );  //接受一个数组,这种情况下进行拷贝传值,在函数中对数组的更改不会影响实参。

void test( vector<int>& elements );  //接受一个数组的引用,形参作为实参的别名,改变形参即改变实参,调用时:test( nums );

void test( vector<int>* elements );  //接受一个指针/地址,拷贝传值(拷贝的是数组的地址),改变地址中的值即改变实参的值。调用时为:test( &nums );  //注意区分vector与数组,数组名为数组头地址,vector不一样,所以需要取地址符号。若为vector<int >* tmp(nums);那么调用方式为test( tmp );

2、返回值传值

vector<int> test(){...return nums;} //返回一个向量类型,产生拷贝构造。

vector<int>* test(){ vector<int>* tmp= new vector<int>[10];....return tmp}; //必须为指针分配存储空间,否则传回来的指针是野指针。

vector<int>& test(){vector<int>* tmp= new vector<int>[10];....return *tmp}; 

此外还有vector的二维形式

但二维还是用数组表示比较方便?

异常抛出(不熟,需要学习加强)

高级版:哈希表

哈希表就是将关键字与值进行配对,在这道题中就是数组中数字的值与它的索引进行配对。

那么算法的基本思想就是建立哈希表,然后在循环中用哈希表查找对应的键值。有两边哈希表与一遍哈希表两种用法。

空间复杂度与时间复杂度都为n。

哈希表的数据结构(关键在于散列函数)

知识点:

Java当中

1、Map

Map是一个接口,是键值对映射的抽象接口。关于Map的介绍,详情见Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)

2、HashMap

Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例 (没咋看懂,要学的还是太多了)

C++当中

map,STL中提供的一种一对一的关联容器,实际上也是哈希表,使用方式:

map<int,int>element;

 

-------------------------

第二道题目:整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

JAVA解答

这道题如果不考虑溢出的话非常简单。但溢出的考虑就比较麻烦了。可以通过try-catch的方式来写,但是这种方式调用大量库函数,比计算更慢。

更好的方式是通过计算来考虑整数的溢出,使用java中integer类的最大值与最小值进行计算就可以了:

class Solution {
    public int reverse(int x) {
        int reverse = 0;
        while (x != 0) {
            int tmp = x % 10;
            if (reverse > Integer.MAX_VALUE / 10 || (reverse == Integer.MAX_VALUE / 10 && pop > 7)) 
                return 0;
            if (reverse < Integer.MIN_VALUE / 10 || (reverse == Integer.MIN_VALUE / 10 && pop < -8)) 
                return 0;
            reverse = reverse * 10 + tmp;
            x /= 10;
        }
        return reverse;
    }
}

其中,7是2^31-1的个位数,-8是-2^31的个位数。

C++解答

在C++中,吧Integer.MAX_VALUE换成INT_MAX与INT_MIN即可

------------------------------------------------------

第三道题目:回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

进阶:

你能不将整数转为字符串来解决这个问题吗?

初级版

这个问题的初级版解答算是整数反转的进阶,即将整数反转之后看看与原数是否相等。

但是在答案核对中,这种方法需要考虑整数溢出问题。按道理,反转后会产生整数溢出的数都不是回文数。所以应当直接返回false,而不是还需要判断来处理溢出。

高级版

取后半段数字进行反转与前半段比较

具体做法如下:

每次进行取余操作 ( %10),取出最低的数字:y = x % 10
将最低的数字加到取出数的末尾:revertNum = revertNum * 10 + y
每取一个最低位数字,x 都要自除以 10
判断 x 是不是小于 revertNum ,当它小于的时候,说明数字已经对半或者过半了
最后,判断奇偶数情况:如果是偶数的话,revertNum 和 x 相等;如果是奇数的话,最中间的数字就在revertNum 的最低位上,将它除以 10 以后应该和 x 相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值