9.回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
思路一:
第一反应转为字符串,遍历字符串首尾是否相等。
class Solution {
public boolean isPalindrome(int x) {
String s=x+"";
for (int i = 0; i < s.length() - 1; i++) {
if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
return false;
}
}
return true;
}
}
也可以使用字符串反转比较
class Solution {
public boolean isPalindrome(int x) {
String s=x+"";
StringBuffer rs= new StringBuffer(s);
if(s.equals(rs.reverse().toString())) {
return true;
}else{
return false;
}
}
}
思路二:
反转一半数字
class Solution {
public boolean isPalindrome(int x) {
if(x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while(x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
return x == revertedNumber || x == revertedNumber/10;
}
}
寻找数组的中心索引
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。
思路一:
以分割点下标对数组进行迭代,分别计算两端数组和。
class Solution {
public int pivotIndex(int[] nums) {
int len = nums.length;
int i=0;
for(;i<len;i++) {
int suml=0;
for(int j=0;j<i;j++) {
suml+=nums[j];
}
int sumr=0;
for(int j=i+1;j<len;j++)
sumr+=nums[j];
if(suml==sumr)
return i;
}
return -1;
}
}
至少是其他数字两倍的最大数
在一个给定的数组nums中,总是存在一个最大元素 。
查找数组中的最大元素是否至少是数组中每个其他数字的两倍。
如果是,则返回最大元素的索引,否则返回-1。
输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.
思路一:
找最大数和次大数
class Solution {
public int dominantIndex(int[] nums) {
int len = nums.length;
int max=0;
int last=0;
int index=0;
for(int i=0;i<len;i++) {
if(nums[i]>max) {
last=max;
max=nums[i];
index=i;
}
else if(nums[i]>last)
last=nums[i];
}
if(max>=2*last) {
return index;
}else {
return -1;
}
}
}
加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
思路一:
从最后一位按位迭代,如果为9则迭代进位。
class Solution {
public int[] plusOne(int[] digits) {
int len=digits.length;
for(int i=len-1;i>=0;i--) {
if(digits[i]!=9) {
digits[i]+=1;
return digits;
}else {
digits[i]=0;
}
}
int [] res=new int[len+1];
res[0]=1;
return res;
}
}
杨辉三角
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
思路一:
从第3行开始,除首尾元素外,每个元素是上行依次两个元素的和。
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> pre=new ArrayList<>();
if(numRows==0)
return res;
pre.add(1);
res.add(pre);
for(int i=1;i<numRows;i++) {
List<Integer> tmp=new ArrayList<>();
tmp.add(1);
for(int j=0;j<pre.size()-1;j++) {
tmp.add(pre.get(j)+pre.get(j+1));
}
tmp.add(1);
pre=tmp;
res.add(pre);
}
return res;
}
}
二进制求和
示例 1:
输入: a = “11”, b = “1”
输出: “100”
思路一:二进制加法规律,两个数求和再对2取余,结果为本位最终值,如果进位则对和除以2得到1至高位求和。
从最低位计算,结果存StringBuffer中,最后反转即得到最终结果。
class Solution {
public String addBinary(String a, String b) {
StringBuffer res= new StringBuffer();
int lena=a.length()-1;
int lenb=b.length()-1;
int sum = 0;
while(lena>=0||lenb>=0) {
int tmp=sum;
if(lena>=0) {
tmp+=(a.charAt(lena)-'0');
lena--;
}
if(lenb>=0) {
tmp+=(b.charAt(lenb)-'0');
lenb--;
}
res.append(tmp%2);
sum=tmp/2;
}
if(sum!=0)
res.append(1);
String re=res.reverse().toString();
return re;
}
}
实现strStr()
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = “hello”, needle = “ll”
输出: 2
思路一:迭代,设置flag跳出。
class Solution {
public int strStr(String haystack, String needle) {
if(needle.equals(""))
return 0;
char [] cha=haystack.toCharArray();
char [] chb=needle.toCharArray();
int res=-1;
for(int i =0;i<=cha.length-chb.length;i++) {
boolean flag=true;
for(int j=0;j<chb.length;j++) {
if(cha[i+j]!=chb[j]) {
flag=false;
break;
}
}
if(flag==true)
return i;
}
return res;
}
}
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
思路一:
先找到数组中最短元素,最长公共子串不会超过最短元素
对第一个元素迭代分割,分割后的子串用于迭代比较是否相同。
class Solution {
public String longestCommonPrefix(String[] strs) {
String res="";
if(strs==null||strs.length==0){
return res;
}
if(strs.length==1){
return strs[0];
}
int min = strs[0].length();
for(int i=1;i<strs.length;i++) {
if(min>strs[i].length())
min=strs[i].length();
}
int i=1;
boolean flag = true;
for (i = 1; i <= min; i++) {
String tmp = strs[0].substring(0, i);
for (int j = 0; j < strs.length; j++) {
if (!tmp.equals(strs[j].substring(0, i))) {
flag = false;
break;
}
}
if (flag == false) {
if(i==1) {
return "";
}else {
return strs[0].substring(0, i - 1);
}
}
if (flag == true && i==min) {
return strs[0].substring(0, i);
}
}
return res;
}
}
反转字符串
编写一个函数,其作用是将输入的字符串反转过来。
示例 1:
输入: “hello”
输出: “olleh”
思路一:双向指针
转成字符数组,首尾两指针向里迭代。
class Solution {
public String reverseString(String s) {
char[] chars=s.toCharArray();
int begin=0;
int end=chars.length-1;
while(begin<end) {
char tmp = chars[begin];
chars[begin]=chars[end];
chars[end]=tmp;
begin++;
end--;
}
return new String(chars);
}
}
思路二:利用StrinBuilder
class Solution {
public String reverseString(String s) {
String res="";
StringBuilder strs= new StringBuilder(s);
strs.reverse();
res=strs.toString();
return res;
}
}
拓展:
句子中单词反转。
例如:
输入:“student. a am I”
输出:“I am a student.”
思路一:反转两次
public class Solution {
public String ReverseSentence(String str) {
if(str.length()==0||str.trim().length()==0)
return str;
char[] chars = str.toCharArray();
int mark=0;
for(int i=0;i<chars.length;i++) {
if(chars[i]==' ') {
swapStr(chars,mark,i-1);
mark=i+1;
}
}
swapStr(chars,mark,chars.length-1);
swapStr(chars,0,chars.length-1);
return new String(chars);
}
public static void swapStr(char[] chars,int begin,int end) {
while(begin<end) {
char tmp = chars[begin];
chars[begin]=chars[end];
chars[end]=tmp;
begin++;
end--;
}
}
}
思路二:StringBuilder数据结构
public class Solution {
public String ReverseSentence(String str) {
if(str.length()==0||str.trim().length()==0)
return str;
String [] strs=str.split(" ");
StringBuffer sb= new StringBuffer();
for(int i=strs.length-1;i>=0;i--){
sb.append(strs[i]);
if(i>0)
sb.append(" ");
}
return sb.toString();
}
}
数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:
输入: [1,4,3,2]
输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
思路一:排序后只对偶数求和。
class Solution {
public int arrayPairSum(int[] nums) {
Arrays.sort(nums);
int sum=nums[0];
for(int i=2;i<nums.length;i+=2) {
sum+=nums[i];
}
return sum;
}
}
两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
思路一:二分法
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] res = new int [2];
for(int i=0;i<numbers.length;i++) {
int t=target-numbers[i];
int begin=i+1;
int end=numbers.length-1;
while(begin<=end) {
int mid=(begin+end)/2;
if(t==numbers[mid]) {
res[0]=i+1;
res[1]=mid+1;
return res;
}
else if(t>numbers[mid]) {
begin=mid+1;
}
else if(t<numbers[mid])
end=mid-1;
}
}
return res;
}
}
移除元素
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2
你不需要考虑数组中超出新长度后面的元素。
思路:快慢指针
class Solution {
public int removeElement(int[] nums, int val) {
int k=0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=val){
nums[k++]=nums[i];
}
}
return k;
}
}
最大连续1的个数
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
思路一:
两层迭代
class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
int count = 0;
int left = 0;
for (int i = 0; i < nums.length; i++) {
int tmp=0;
for (int j = i; j < nums.length; j++) {
if (nums[j] == 1) {
tmp++;
} else if(nums[j] ==0)
break;
}
if(tmp>count) {
count=tmp;
}
}
return count;
}
}
思路二:
一次迭代,如果为1则加一,为0存储最大值,计数为0重新计数。
class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
int count=0;
int max=0;
for(int i=0;i<nums.length;i++) {
if(nums[i]==1)
count++;
else {
max=Math.max(count, max);
count=0;
}
}
return Math.max(count, max);
}
}