66 加一问题
思路: 加1之后变为两位数,则进行求余,将余数放进数组最后一位,然后两位数进行进位,当数组元素全是9时才出现进位扩容情况。判断是否需要扩容,需要则新数组第一位为1 其余元素为0。
package arrayTest;
public class AddOne66 {
public static void main(String[] args) {
}
public int[] plusOne(int[] digits){
int num=0;
int carry=1;
for(int i=digits.length-1;i>=0;i--){ //从数组最后一个数开始遍历 最后一个数字+1
num=digits[i]+carry; //最后一位+1
digits[i]=num%10; //加一后的值求余放入数组最后一位
carry=num/10; //判断是否需要进位
if(carry==0){
break; //不进位就不用再对其他数组元素进行计算
}
}
if(carry==0){
return digits;
}
int arr[]=new int [digits.length+1]; //数组扩容
arr[0]=1; //第一个元素为1 其他元素为0
return arr;
}
}
136 只出现一次的数
思路: 异或
-
a ^ b ^ c <=> a ^ c ^ b
-
任何数于0异或为任何数 0 ^ n => n
-
相同的数异或为0: n ^ n => 0
//只出现一次的数字 异或求法
public static int Find_Num(int arr[]){
int res=0;
for (int i = 0; i < arr.length; i++) {
res^=arr[i];//异或 值相同为0 0和a异或为a
}
return res;
}
}
724 寻找数组的中心索引
思路: 1. 把索引左边的数值加起来和右边数值比较 相等则为中心索引
2.左边的值每次进行查找中心索引时累加 右边的值用总数减去左边的值和索引值。
package arrayTest;
//寻找数组中心索引
public class PivotIndex724 {
public static void main(String[] args) {
}
public int pivotIndex(int[] nums) {
if(nums.length<=1){ //数组元素只有1个 无中心索引
return -1;
}
int sum=0;
for (int i = 0; i < nums.length; i++) {
sum+=nums[i];
}
int rightNums=0;
int LeftNums=0;
for (int i = 0; i < nums.length; i++) {
if(i==0){
LeftNums=0;
}else{
LeftNums+=nums[i-1];
}
rightNums=sum-nums[i]-LeftNums;
if(rightNums==LeftNums){
return i;
}
}
return -1;
}
}
268 缺失数字
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1]
输出: 2
思路: 1. 先使用Arrays.sort()方法给数组排序。2. 判断0不在第一个位置和n不在最后一个位置
3. 判断缺失元素前一个元素加一是否等于后一个元素 不等于则找到缺失元素
package arrayTest;
//缺失数字
import java.util.Arrays;
public class LoseNumber268 {
public static void main(String[] args) {
int []nums={0,1,2,3,5};
System.out.println(missingNumber(nums));
}
public static int missingNumber(int[] nums) {
Arrays.sort(nums);//对数组进行从小到大排序
if(nums[0]!=0){ //0不在首位
return -1;
}else if(nums[nums.length-1]!=nums.length){ //n不在末尾
return -1;
}
for (int i = 0; i < nums.length; i++) {
int sum=nums[i+1];
if(sum!=nums[i]+1){
return i+1;
}
}
return -1;
}
}
167 两数之和 II - 输入有序数组
思路: 双指针 左右指针一起动,计算两个指针元素之和,若相等则找到,小于所求值则左指针右移,大于则右指针左移。
public int[] twoSum(int[] numbers, int target) {
int L=0; //左指针
int R=numbers.length-1; //右指针
while(L<R){
int sum=numbers[L]+numbers[R]; //两数之和
if(sum==target){
return new int[]{L+1,R+1}; //返回求出的下标
}else if(sum<target){
L++;
}else{
R--;
}
}
return null; //没找到 返回空
}
189 旋转数组
思路:旋转1次 将最后一个元素和第一个元素位置互换,最后一个元素再和第二个元素互换....(用一个for循环)
旋转n次 外层一个for循环 控制选择次数 内层一个循环 控制所有元素位置后移。
public static void tate(int[] nums, int k) {
int temp;
for (int i=0;i<k;i++) { //旋转次数
int number=nums[nums.length-1];
for (int j = 0; j < nums.length; j++) { //数组元素位置后移
temp=nums[j];
nums[j]=number;
number=temp;
}
}
System.out.println(nums);
}
905 按奇偶排序数组
思路:第一种 定义新数组 定义变量a从0开始,找到偶数存放进新数组中。定义变量b从数组最后一个元素位置开始放奇数。
第二种 双指针 4种情况 左奇右偶,左奇右奇,左偶右偶,左偶右奇 分别进行指针变化操作和奇偶交换
public int[] sortArrayByParity1(int[] A) {
int B[]=new int[A.length]; //定义新数组
int a=0; //a负责偶数存储
int b=A.length-1; //b负责奇数存储
for(int i=0;i<A.length;i++){
if(A[i]%2==0){
B[a]=A[i]; //将偶数从新数组第一个元素开始存储
a++;
}else{
B[b]=A[i]; //将奇数从新数组最后一个元素开始存储
b--;
}
}
return B;
}
public int[] sortArrayByParity2(int[] A) {
int L=0;
int R=A.length-1;
int n=0;
while(L<R){
if(A[L]%2==1&&A[R]%2==1){ //左奇右奇
R--;
}else if(A[L]%2==1&&A[R]%2==0){ //左奇右偶 元素交换
A[L]=A[L]+A[R];
A[R]=A[L]-A[n];
A[L]=A[L]-A[n];
}else if(A[L]%2==0&&A[R]%2==1){ //左偶右奇
L++;
R--;
}else //左偶右偶
L++;
}
return A;
}
169 求众数
思路: 三国大战 擂台放入数组第一个元素
后面数字一样计数加一
不一样 两个数字抵消 计数减少
擂台重新进入元素
最后留下的就是所求众数
public int majorityElement(int[] nums) {
int result=nums[0];
int count=1;
for (int i = 1; i < nums.length; i++) {
if(nums[i]==result){ //数字相同
count++; //计数加一
}else{
count--; //不同抵消 计数减一
if(count==0){
result=nums[i]; //擂台上没有数字 重新放入
count=1;
}
}
}
return result;
}
88 合并两个有序序列
思路:定义一个变量IndexEnd 大小为nums1和nums2长度之和-1,从后往前分别比较两个nums1[i]与nums2[i]大小,如果nums1大则将nums1的元素放在nums1新长度数组的后面,如果nums2大则将nums2的元素放在nums1新长度数组的后面,每执行一次操作数组下标左移。最后需要判断nums2的元素有没有全放入nums1中,如果没有说明nums2剩余元素小于nums1元素 则直接放入nums1中。
public void merge(int[] nums1, int m, int[] nums2, int n) {
int index1=m-1; //nums1下标
int index2=n-1; //nums2下标
int indexEnd=m+n-1; //合并后nums1下标
while(index1>=0&&index2>=0){
if(nums1[index1]>nums2[index2]){ //nums1元素大
nums1[indexEnd--]=nums1[index1--]; //nums1元素存入合并后数组,数组下标左移
}else{
nums1[indexEnd--]=nums2[index2--]; //nums2元素存入合并后数组,数组下标左移
}
}
if(index2>=0){ //判断nums2是否都放进nums1中
for(int i=0;i<=index2;i++){
nums1[i]=nums2[i];
}
}
}
344 反转字符串
思路:双指针 左指针从0出发 右指针从length-1出发,左指针和右指针元素互换。
public void reverseString(char[] s) {
int L=0; //左指针
int R=s.length-1; //右指针
char temp;
while(L<R){
//元素交换
temp=s[L];
s[L]=s[R];
s[R]=temp;
L++;
R--;
}
}
485 最大连续1的个数
思路:碰到1 计数加1 碰到0比较那一次连续1计数大 最后输出最大的个数。
public int findMaxConsecutiveOnes(int[] nums) {
int res=0;
int count=0;
for (int i = 0; i < nums.length; i++) {
if(nums[i]==1){ //碰到1
count++;
}else{ //碰到0
res=count>res?count:res;
count=0;
}
}
return res>count?res:count;
}
53 最大子序和
思路:对数组进行遍历,当前最大连续子序列和为 sum,结果为 ans
如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字
如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字
每次比较 sum 和 ans的大小,将最大值置为ans,遍历结束返回结果
public int maxSubArray(int[] nums) {
int sum=0;
int max=nums[0];
for(int i=0;i<nums.length;i++){
if(sum>0){ //对结果有增益
sum+=nums[i]; //累加
}else{
sum=nums[i]; //重置
}
max=Math.max(max,sum);
}
return max;
}
747 至少是所有元素两倍的最大数
思路:找到第二大数字,最大数字大于第二大数字的两倍则为最大数字
public int dominantIndex(int[] nums) {
int index=0;
int secondMax=0;
for(int i=1;i<nums.length;i++){
if(nums[i]>nums[index]){ //大于最大元素
secondMax=nums[index]; //更新第二大
index=i;
}else if(nums[i]>secondMax){ //小于最大元素大于第二大
secondMax=nums[i]; //更新第二大
}
}
if(nums[index]>=secondMax*2)
return index;
return -1;
}
242 有效的字母异位词
思路:第一种:将字符串转换为字符数组,然后进行数组排序,调用equals比较两个字符串是否相等。
第二种:定义长度为26的数组,将s字符串中的字母分别对应数组26个位置,出现一次数组元素加一。t字符串中的字母出现一次减一,最终遍历数组,每一位元素都为0则为异位词。
//第一种思路
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())
return false;
char c1[]=s.toCharArray(); //转为字符串数组
char c2[]=t.toCharArray();
Arrays.sort(c1); //排序
Arrays.sort(c2);
return Arrays.equals(c1,c2); //判断相等
}
//第二种思路
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())
return false;
int arr[]=new int[26]; //26长度的数组 对应26个小写字母
for(int i=0;i<s.length();i++){
arr[s.charAt(i)-'a']++; //字母对应的数组位置值增加
arr[t.charAt(i)-'a']--; //字母对应的数组位置值减小
}
for(int x:arr)
if(x!=0) //判断数组每一位是否为0 为0则表明是异位词
return false;
return true;
}