常见算法题目<第1天>
判断是否为回文字符串
方法1分析:
所谓回文串
”就是指一个字符串无论正读还是反读,都是一样的字符;
基于此,对“a”字符串进行𝑙𝑒𝑛/2
次判断, 如果出现一次𝑠𝑡𝑟[𝑖] != 𝑠𝑡𝑟[𝑙𝑒𝑛−1−𝑖]
那就不是回文,𝑙𝑒𝑛/2
次判断全都相等,就为回文串;
代码实现:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param str string字符串 待判断的字符串
* @return bool布尔型
*/
public boolean judge (String str) {
//求字符串str长度
int len=str.length();
//对一半进行判断
for(int i=0;i<len/2;i++){
if(str.charAt(i)!=str.charAt(len-1-i))
return false;
}
return true;
}
}
方法2分析:借助两个指针
;
- 一个指针指向第一个字符,一个指针指向最后一个字符;
- 两个指针同时往中间走;
- 过程中出现不相同的字符,则为
false
,否则为true
;
代码实现:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param str string字符串 待判断的字符串
* @return bool布尔型
*/
public boolean judge (String str) {
if(str.length()==0){
return true;
}
//借助两个指针
// 左指针指向第一个字符
//右指针指向最后一个字符
int left=0;
int right=str.length()-1;
while(left<right){
if(str.charAt(left++)!=str.charAt(right--))
return false;
}
return true;
}
}
截断句子
分析:
由题意可知:除了最后一个单词外,前面的单词均以空格结尾;
因此,分两步完成:
- 统计空格与句子结尾的数目以统计单词数目
count
; - 当
count==k
时,将当前的下标纪录到end
,返回在end
处截断的句子;
代码实现:
class Solution {
public String truncateSentence(String s, int k) {
//求字符串的长度
int n = s.length();
int end=0;
int count=0;
//循环遍历
for(int i=1; i<=n;i++){
if(i==n || s.charAt(i)==' '){
count++;
if(count==k){
end=i;
break;
}
}
}
//substring():返回字符串的子字符串,0为起始位置(包括),end为结束位置(不包括)
return s.substring(0, end);
}
}
删除有序数组中的重复项
分析:
利用数组有序的特点,可以通过 双指针的方法 删除重复元素,快指针依次遍历1
到n-1
的每个位置,如果nums[fast]不等于nums[fast-1]
,说明nums[fast]
和之前的元素都不相同,此时,将nums[fast]
的值复制到nums[slow]
中,然后,slow
值加1
,即指向下一个位置;
分以下情况:
- 数组为空时,返回
0
; - 数组不为空时,最少包含一个元素,因此快慢指针从下标为1的位置开始;
代码实现:
class Solution {
public int removeDuplicates(int[] nums) {
int n=nums.length;
//数组为空时
if(n==0){
return 0;
}
//定义快慢指针,均从下标为1的位置开始
int fast=1;
int slow=1;
while(fast<n){
if(nums[fast-1]!=nums[fast]){
//说明前面元素均不相同
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
移除元素
分析:
由于题目要求删除数组中等于 val
的元素,因此输出数组的长度一定小于等于输入数组的长度,我们可以把输出的数组直接写在输入数组上。
使用双指针
:右指针right
指向当前将要处理的元素,左指针 left
指向下一个将要赋值的位置;
- 如果右指针指向的元素不等于
val
,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移; - 如果右指针指向的元素等于
val
,它不能在输出数组里,此时左指针不动,右指针右移一位;
代码实现:
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length;
//定义两个指针:left right
//左指针指向下一个将要赋值的位置
//右指针指向将要处理的元素的位置
int left = 0;
for(int right =0;right < n;right++){
if(nums[right] != val){
nums[left] = nums [right];
left++;
}
}
return left;
}
}
罗马数字转整数
分析:
分两种情况分析:
- 非特殊情况
(小的数字在大的数字的右边)
转换方法
:累加每个字符对应的数值;
- 特殊情况
(小的数字在大的数字的左边)
转换方法
:若一个数字右侧的数字比它大,则将该数字的符号取反,简言之就是取反;
代码实现:
class Solution {
public int romanToInt(String s) {
// 添加剩余6种对照情形
s = s.replace("IV","a");
s = s.replace("IX","b");
s = s.replace("XL","c");
s = s.replace("XC","d");
s = s.replace("CD","e");
s = s.replace("CM","f");
// 统计罗马字符和
int res = 0;
for (int i = 0; i < s.length(); i++) {
res += getValue(s.charAt(i));
}
return res;
}
//添加对照表
public int getValue(char c) {
switch(c) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
case 'a': return 4;
case 'b': return 9;
case 'c': return 40;
case 'd': return 90;
case 'e': return 400;
case 'f': return 900;
}
return 0;
}
}
丑数
OJ链接
分析:
根据丑数的定义,
0
和负整数一定不是丑数;
可以对n
反复除以 2,3,5,直到n
不再包含质因数 2,3,5;
若剩下的数等于 1,则说明n
不包含其他质因数,是丑数;否则,说明n
包含其他质因数,不是丑数;
代码实现:
class Solution {
public boolean isUgly(int n) {
//0及负数不是丑数
if (n <= 0) {
return false;
}
int[] factors = {2, 3, 5};
for (int factor : factors) {
while (n % factor == 0) {
n /= factor;
}
}
return n == 1;
}
}