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;
}