给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
class Solution {
public int reverse(int x) {
int rev = 0;
while(x != 0){
//Integer.MAX_VALUE代表int类型能取到的最大值,Integer.MIN_VALUE是最小值
//一但rev大于最大值除以10,那么后面rev乘10的时候就要移除,所以要提前判断,返回0
if(rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10){
return 0;
}
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
}
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
class Solution {
public boolean isPalindrome(int x) {
//带有负号,肯定不是回文数
if(x < 0){
return false;
}
//后面要对x进行修改,将其数值先用save保存下来
int save = x;
int result = 0;
//获得x的倒序result
while(x != 0){
result = result * 10 + x % 10;
x /= 10;
}
//判断正序倒序是否相等
if(result == save){
return true;
}
return false;
}
}
给你一个 非严格递增排列 的数组 nums ,请你原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
● 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
● 返回 k 。
class Solution {
public int removeDuplicates(int[] nums) {
//可以将nums[index]看作一个新数组
//不重复的就赋值到nums[index]中,重复的就不赋值了
int index = 0;
//需要把后一个数跟前一个相比,所以i从1开始
for (int i = 1; i < nums.length; i++) {
//找到不重复的元素,赋值到数组中
//若nums[i]不重复,则添加到nums[index]中,并且将index索引加一
//若nums[i]重复了,就不放进去了,无需操作
if (nums[i] != nums[index]) {
nums[++index] = nums[i];
}
}
//index是索引,元素个数也就是数组长度应该是index+1
return index + 1;
}
}
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
class Solution {
public int removeElement(int[] nums, int val) {
//定义一个cur指向最新修改的位置
//cur从0开始,若元素不需要被删除,则加入nums[cur]中,若需要删除则不加入,
//可以将nums[cur]看作一个新数组,只不过内存空间借用了原来的数组nums
int cur = 0;
for(int i = 0; i < nums.length; i++){
//若nums[i]等于val,说明要删除,就不往数组里放了
if(nums[i] != val){
//nums[i]不等于val,那么就不需要移除,填入到nums[cur],并且将cur加一
nums[cur++] = nums[i];
}
}
//返回长度
return cur;
}
}
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
class Solution {
public int searchInsert(int[] nums, int target) {
//查找的时间复杂度为O(log n),容易想到二分查找
//left为左边界,right为右边界,ans记录索引
int left = 0, right = nums.length - 1, ans = nums.length;
while(left <= right){
// >> 1 其实就是除以2的意思,但是因为是对二进制数直接右移操作,能够节省计算时间
//采用right + ((left - right) >> 1能够有效防止left+right的值过大导致溢出,我认为是一个好习惯
int mid = right + ((left - right) >> 1);
if(target <= nums[mid]){
//下面这两条语句能够保证ans移动到right的右一位,即目标值不存在时应该插入的位置
ans = mid;
right = mid - 1;
}else{
left = mid + 1;
}
}
return ans;
}
}
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
class Solution {
public int lengthOfLastWord(String s) {
//最后一个单词,直接倒着来,index是s的最后一位的索引
int index = s.length() - 1;
//等于空格就一直移动,直到找到字母停止移动
while(s.charAt(index) == ' '){
index--;
}
int wordLength = 0;
while(index >= 0 && s.charAt(index) != ' '){
wordLength++;
index--;
}
return wordLength;
}
}
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//为了节省空间,不创建第三个数组,直接在nums1中排列
//因为nums1的长度为m+n,后边是有足够的空间的,所以我们从后边开始从大到小填入nums1
//定义p1指向nums1中接下来要比较的数值,定义p2指向nums2中接下来要比较的数值
int p1 = m - 1, p2 = n - 1;
//定义索引,从nums1的最末尾开始
int index = m + n - 1;
//p1和p2均大于等于0时,两个原本的数组都还有数据,此时要循环比较
while(p1 >= 0 && p2 >= 0){
//谁大索引处就放谁
if(nums1[p1] >= nums2[p2]){
nums1[index] = nums1[p1];
p1--;
index--;
}else{
nums1[index] = nums2[p2];
p2--;
index--;
}
}
//当nums1中原本的数值都已经比较完了以后,p1为-1,此时直接将nums2中的所有数值按序填入
//若此时p2也为负,则循环不会进行,程序结束
if(p1 < 0){
for(int i = p2; i >= 0; i--){
nums1[i] = nums2[i];
}
}
//只需要判断p1小于0,因为本次排序是直接使用的nums1,所以
//当p2先为负时,p1就算有值,也已经按序排好在nums1中最前面的位置了
}
}
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
class Solution {
public boolean isPalindrome(String s) {
//定义left从字符串的第一位往后遍历,right从字符串的最后一位往前遍历
int left = 0, right = s.length() - 1;
while(left < right){
//取出对应索引出的字符
char cl = s.charAt(left);
char cr = s.charAt(right);
//注意这里有个!
//判断字符是否为数字或者字母,如果不是,就直接移动指针
if(!(('0' <= cl && cl <= '9') || ('A' <= cl && cl <= 'Z') || ('a' <= cl && cl <= 'z'))){
left++;
continue;
}
if(!(('0' <= cr && cr <= '9') || ('A' <= cr && cr <= 'Z') || ('a' <= cr && cr <= 'z'))){
right--;
continue;
}
//将小写字母-32转换为大写字母,原因有二:
//1.本题要求无视字母大小写,只要是同一个字母,不管大写还是小写都视为相同
//2.如果直接判断传入的字符-32,那么可能会导致大写字母转换为数字,然后和数字相等的情况
//ASCII码表中,0~9对应范围48~57,A~Z对应范围65~90
//所以大写字母是有可能被误判成与数字相等的,比如,本来只想得到诸如'a'-32='A'这样的结果
//但是比如把'P'-32,就会得到'0',造成大写字母与数字判定相等的情况。('P'对应80,'0'对应48)
if('a' <= cl && cl <= 'z'){
cl -= 32;
}
if('a' <= cr && cr <= 'z'){
cr -= 32;
}
//这里就可以放心地直接比较两个字符是否相等了,不相等直接返回false,相等的话移动指针,继续遍历比较
if(cl != cr){
return false;
}
left++;
right--;
}
return true;
}
}
之前单门发过这道题的题解,并且还扩展了两道相关的题目,一共三道算法题,文章地址如下:
算法|只出现一次的数字I,II,III
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
class Solution {
public int[] plusOne(int[] digits) {
//这个题的思路是:如果最后一位不是9,那么就可以直接给最后一位加1
//如果最后一位是9,就要往前找,找到第一个不是9的地方,将其加1。而在此之前遍历过的9都要改为0
//如果这个数全是9,那么就创建一个新的比digits长度大1的数组,数组首位为1,其他位置0
//最后一位不是9,直接加1并返回数组
if(digits[digits.length - 1] != 9){
digits[digits.length - 1] += 1;
return digits;
}
//遍历过的9都改为0,将第一个遇到的不是9的数加1,并且返回数组
for(int i = digits.length - 1; i >= 0; i--){
if(digits[i] == 9){
digits[i] = 0;
}else{
digits[i]++;
return digits;
}
}
//能进行到这一步,说明刚才遍历整个数组都是9所以才没有返回数组
//因为遍历的时候将9都改为了0,所以此时数组的首位元素也是0
if(digits[0] == 0){
//创建新数组,首位赋值为1,其余位置均为0,因为数组中默认值为0,所以其他位置就不赋值了
int[] newDigits = new int[digits.length + 1];
newDigits[0] = 1;
return newDigits;
}
return null;
}
}
如果对您有帮助,请点赞关注支持我,谢谢!
如有错误或者不足之处,希望您能够加以指正!