下面总结下自己做过的数组编程题
LeetCode
66.加一问题
解析:
这里有好多种情况。如果数组啊A[i]=9 或者都是9的情况下
那么从后面往前判断 如果num/10等于0的话 那么直接结束循环 如果等于1 就说明数字是9 那么就进行下一次循环
此处用A[i]=num%10赋值
如果数组里全是9 那么就要创建一个比原数组大一个长度的新数组,那么新数组的第一个角标A[0]=1 ,后面的全是0
import java.util.Arrays;
class LeetCode66{
public static void main(String[] args){
int[] digits={9,9,9,9,9};
System.out.println(Arrays.toString(plusOne(digits)));
}
public static int[] plusOne(int[] digits){
int carry=1;
for(int i=digits.length-1;i>=0;i--){
int num=digits[i]+carry;
digits[i]=num%10; //把当前的数字赋给digits[i] 如果是10 赋值0
carry=num/10; //如果num=10时 carry=1 进行下一次循环
if(carry==0){ //如果为0说明结束循环皆可以
break;
}
}
if(carry==1){
int[] arr=new int[digits.length+1];//创建一个新数组长度加一
//遍历完毕后如果carry=1时那么就说明列表里全是9
arr[0]=1;//把初值变为1 后面默认为0
return arr;
}
return digits;
}
}
169.多数元素
解析1:
该题有一个关键点就是这个元素出现次数大于length/2
所以有一个比较巧妙的方法 就是从左往右遍历 如果后面的值和前面的值相等 那么计数器加一;
如果不相等,计数器减一,如果计数器减到0时候说明前面有两个数出现的次数是相等的,此时记录nums[i]的值 计数器重新为1
进行下一个数的比较,这个题只是让找到这个值而已
解析2
先把它升序排序
从左到右 先考虑出情况 遍历元素出现的次数大于length/2 那么就跳出循环
这里定义两个指针 i j , i不动让j动 如果i和j对应的元素相等 那么计数器加一 j往后挪 如果不相等那么就跳出循环
如果此时的计数器大于先前的最大值,那么更新最大值,然后让i从i+count处再进行下一次遍历
class Solution169 {
public int majorityElement(int[] nums) {
//不使用排序 在O(n)解决
int m=nums[0];
int count=1;
for(int i=1;i<nums.length;i++){
if(nums[i]==m){
count++;
//就等于说相等就加一 不相等就减一 然后再让m更新值
// 让后面的再进行比较如果相等计数加一 直到遍历结束
}else{
count--;
if(count==0){
m=nums[i];
count=1;
}
}
}
return m;
/*
Arrays.sort(nums); //O(n*logn)
return nums[nums.length/2];
*/
/*
Arrays.sort(nums);
int m=0;
int mcount=0;
for(int i=0;i<nums.length;){
if(i>nums.length/2){
break;
}
int count=1;
for(int j=i+1;j<nums.length;j++){
if(nums[j]==nums[i]){
count++;
}else{
break;
}
}
if(count>mcount){
mcount=count;
m=nums[i];
}
i+=count;
}
return m;
*/
}
}
209.长度最小的子数组
解析:遍历值然后依次加到sum中 判断sum和s的值的大小
如果大于s那么长度减一 依次判断长度最小的len
i往后移动 直到条件不满足为止
class Solution209 {
public int minSubArrayLen(int s, int[] nums) {
int len=0;
int i=0;
int sum=0;
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=s){
len=len==0?(j-i+1):Math.min(len,j-i+1); //判断长度最小的
sum-=nums[i];
i++;
}
}
return len;
}
}
283.移动零
解析:从左到右遇到0不用管 遇到不是0和前面交换就行 因为是从左到右依次遍历 利用两个指针来依次交换。
class LeetCode{
public static void main(String[] args){
int[] nums={2,5,0,5,0,1,3};
moveZeroes(nums);
}
public static void moveZeroes(int[] nums){
int k=0;
int temp=0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=0){ //遇到0不管跳过 当遇到不是0的进行换值
temp=nums[i];
//假设i前面有一个0,那么就得把nums[k]和nums[i]换位置
//因为nums[k]一旦停住那么永远指的是0的那个元素位置
nums[i]=nums[k];
nums[k]=temp; //然后换了之后把nums[k]换成此时i指的那个值
k++;
}
}
}
}
674.最长连续递增序列
解析:还是利用两个指针来表示
如果前者比后者小 那么计数器加一,右指针加一 如果还小那么右指针继续移动 每次都会把count值赋给Maxcount
如果出现比后者大的数字那么重置count l往后移动 r也往后移动1 再进行比较
class LeetCode674{
public static void main(String[] args){
int[] nums={1,3,4,5,7};
findLengthOfLCIS(nums);
}
public static int findLengthOfLCIS(int[] nums){
if(nums.length<=1){
return nums.length;
}
int maxl=0;
int maxr=0;
int l=0;
int r=0;
int maxCount=1;
int count=1;
for(int i=0;i<nums.length;i++){
if(nums[i]<nums[i+1]){
count++; //当时从小到大排序的时候 计数长度
r=i+1; //最右边指针的位置
}else{
count=1; //如果出现比他大的数那么重置count=1
l=i+1; //把左指针挪到i+1的位置进行再次比较长度
r=i+1; //把右边指针挪到i+1的位置进行再次比较
}
if(count>maxCount){
maxCount=count;//把count计数赋给maxCount
maxl=l; //把此时的l和r记录到maxl和maxr中
maxr=r;
}
}//知道循环结束找到 最大长度maxCount
System.out.println(maxl+"~"+maxr);
return maxCount;
}
}
724.寻找数组的中心索引
解析:
计算总和 把左边用left表示 右边用right表示 那么中间的值就是i往后依次移动判断left是否等于right
如果等于那么就输出A[i]
如果循环完了没有相等的 那么就说返回-1
class LeetCode724{
public static void main(String[] args){
int [] nums={1,7,3,6,5,6,};
pivotlndex(nums);
}
public static int pivotlndex(int [] nums){
int sum=0; //计算总和
for(int num:nums){
sum+=num;//把数组里所有元素加起来
}
int leftsum=0;
int rightsum=0;
for(int i=0;i<nums.length;i++){
if(i==0){
leftsum=0;//第一个数字左边肯定得是0
}else{
leftsum+=nums[i-1]; //nums[i]的左边之和
//因为必须把左边的数字全部求和和右边比那么就必须设立nums[i]是这个中间值
}
rightsum=sum-nums[i]-leftsum; //总和把中间值和左边总和减去是否和右边总和相等
if(rightsum==leftsum){ //如果相等那么此时i就是中间值
return i;
}
}
return -1;//表示没找到
}
}
905.按奇偶排序数组
解析:定义两个指针一个从左边出发 ,一个从右边出发
如果左边为奇数右边为偶数那么交换
如果左右两边都是偶数则往中间夹逼
剩下的就是左右两边都是奇数 那么就移动右边 知道找到一个是偶数 然后在进行第一步的交换
class LeetCode905{
public static void main(String[] args){
int [] nums={3,1,2,4};
System.out.println(sortArrayByParity(nums));
}
public static int[] sortArrayByParity(int[] A){
int left=0;
int right=A.length-1;
while(true){
if(A[left]%2==1&&A[right]%2==0){ //把左边为奇数和右边为偶数的交换
int temp=A[left];
A[left]=A[right];
A[right]=temp;
}else if(A[left]%2==0&&A[right]%2==0){
//如果左右两边都是偶数的话,那么左右两个指针同时往中间移动
left++;
right--;
}else{
right--; //剩下的就是左右两边都是奇数的话那么就移动右边 直到找到一个是偶数
}
}
}
}
1013.将数组分成和相等的三个部分
解析:首先计算出数组元素的总和 用到foreach语句比较方便
然后判断每一部分的和key是多少
然后从左到右遍历 每遍历一个 key减去那个值直到key=0 计数器此时加一 重置key值 进行下一次循环
循环结束后 当计数器加到3时说明出现了3部分之和相等 则返回true
import java.net.CacheRequest;
class LeetCode1013{
public static void main(String[] args){
int [] nums={0,2,1,-6,6,-7,9,1,2,0,1};
System.out.println(canThreePartsEqualSum(nums));
}
public static boolean canThreePartsEqualSum(int[] A){
int sum=0;
for(int num:A){
sum+=num; //遍历数组所有值计算总和
}
int key=sum/3; //题目要求是分为三等分 那么计算出每一等分是多少
int group=0;
for(int i=0;i<A.length;i++){
key-=A[i]; //从左到右依次进行减
if(key==0){ //当key减到0时候那么就是说找到一部分
group++; //所以计数器加一
key=sum/3; //重置key的值进行下一部分的运算
}
}
return group==3; //计数器到三所以说此数组满足 true or false
}
}
1295.统计位数为偶数的数字
解析:
就是遍历每一个数组元素 把每个元素用字符串长度表示出来 如果此数是偶数那么就count++ 直到遍历完数组元素
返回count的值即可
class LeetCode1295{
public static void main(String[] args){
int [] nums={12,345,2,6,7895};
System.out.println(findNumber(nums));
//此题容易被误解成返回数组角标为偶数的数字个数
}
public static int findNumber(int[] nums){
int count=0;
for(int i=0;i<nums.length;i++){
if((nums[i]+"").length()%2==0){
//把数组的每个数字表示字符串长度计算是否能被2整除能整除count加一
count++;
}
}
return count;
}
}
1313.
解析:
先遍历原数组偶数角标的所有元素之和 定义为len
然后创建新数组那么新数组的长度就是这些偶数角标所对应的元素之和
遍历原数组奇数角标数字
class LeetCode1313{
public static void main(String[] args){
int [] nums={1,2,3,4};
}
public static int[] decompressRLElist(int[] nums){
int len=0;
for(int i=0;i<nums.length;i+=2){ //因为
len+=nums[i];
}
int [] arr=new int[len]; //定义新数组 那么新数组的长度就是原数组偶数角标的数字
int index=0;
for(int i=1;i<nums.length;i+=2){ //遍历奇数角标的数字
for(int j=0;j<nums[i-1];j++){
/* j代表的是这个偶数数组出现的次数 终止条件是这个角标前一个角标对应的数字
所以遍历一次就给计数器index加个1直到这个偶数数字完为止,再执行外层for循环
*/
arr[index++]=nums[i];
//把这个偶数放进新数组 新数组角标往后移动依次存放 那么这个偶数存放的次数就是num[i-1]的数值
}
}
return arr;
}
}