本文包含了十几道leetcode上数组的简单题,记录在此,希望以后在做题道路上也能一帆风顺,做题不再犯愁!!!
leetcode 01 题目链接
第一种暴力的方法直接双for循环时间复杂度为O(N^2) 效果不太好
代码如下(示例):
public int[] twoSum(int[] nums, int target) {
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]+nums[j]==target){
return new int[]{i,j};
}
}
}
return new int[]{};
第二种利用map存储值和下标位置 遍历一边就可以了 时间复杂度为O(N)
代码如下(示例):
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
map.put(nums[0],0);
for(int i=0;i<nums.length;i++){
int count=target-nums[i];
if(map.containsKey(count)){
int index1=map.get(count);
int index2=i;
return new int[]{index1,index2};
}else {
map.put(nums[i],i);
}
}
return null;
}
leetcode 26 题目链接
定义快慢指针 慢指针返回不重复数组长度的下标,快指针定义要交换的位置
代码如下(示例):
public int removeDuplicates(int[] nums) {
if(nums.length==0){
return 0;
}
//用快慢指针
int fast=1;//要检测的位置
int slow=0;//交换位置 或者返回长度位置
while(fast<nums.length){
if(nums[slow]!=nums[fast]){
nums[slow+1]=nums[fast];
slow++;
}
fast++;
}
return slow+1;
}
leetcode 27 题目链接
代码如下(示例):
public int removeElement(int[] nums, int val) {
// i 检验是否==val 等于跳过 不等于赋值
//j 为计数位置
int j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=val){
nums[j]=nums[i];
j++;
}
}
return j;
}
leetcode 35 题目链接
该题很容易想,直接遍历一边就行了 ,如果遇到比目标值大的返回该下标就好了,如果一直没有就插入到最后一个位置即可。
代码如下(示例):
public int searchInsert(int[] nums, int target) {
for(int i=0;i<nums.length;i++){
if(nums[i]==target){
return i;
}
if(nums[i]>target){
return i;
}
}
return nums.length;
}
leetcode 53 题目链接
这道题呢是求出最大子序列的和,可以定义双变量,一个存储最大值(max),另一个是累加和(count)
注意:不能将max和count 定义为0;可能是全负序列。
遍历的过程中,max一直存储的是最大值,count如果变为负数就重新计数累加即可找到最大值。
代码如下(示例):
public int maxSubArray(int[] nums) {
int count=nums[0];
int max=nums[0];
for(int i=1;i<nums.length;i++){
if(count<0){
count=nums[i];
}else {
count+=nums[i];
}
max=Math.max(count,max);
}
return max;
}
leetcode 66 题目链接
这道题刚开始没有理解意思,以为就是简单往最后一个元素加一,报错才发现还有进制,那就多加一位首位为1就好了。
代码如下(示例):
public int[] plusOne(int[] digits) {
for(int i=digits.length-1;i>=0;i--){
digits[i]++;
digits[i]=digits[i]%10;//如果为9 最后一位会变成0 然后给首位加1就可 全是9的序列会变成全为0
if(digits[i]%10!=0){
return digits;
}
}
digits=new int[digits.length+1];
digits[0]=1;
return digits;
}
leetcode 88 题目链接
这道题我先看了看,想了一个偷懒的办法,就是将第二个数组放到第一个数组0元素的位置,之后将数组排序
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i=0;i<nums2.length;i++){
nums1[m]=nums2[i];
m++;
}
Arrays.sort(nums1);
}
之后想了半天从前面排了很久,也没排好主要不想建立一个新的数组,就去看了官方的题解,竟然从后往前找,逆向思维,太牛了!!!
接近双百
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i=m-1;
int j=n-1;
int k=m+n-1;
while(i>=0&&j>=0){
if(nums1[i]>nums2[j]){
nums1[k--]=nums1[i--];
}else{
nums1[k--]=nums2[j--];
}
}
while(j>=0){//即nums2元素还没放完
nums1[k--]=nums2[j--];
}
}
leetcode 118 题目链接
每一列的第一个和最后一个元素都是1
每一行不是1的值都是由其正上方和正上方左边元素相加。
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> list=new ArrayList<>();
int [][]array=new int[numRows][numRows];
for(int i=0;i<numRows;i++){
List<Integer> temp=new ArrayList<>();
for(int j=0;j<=i;j++){
if(j==0||i==j){
array[i][j]=1;
}else{
array[i][j]=array[i-1][j-1]+array[i-1][j];
}
temp.add(array[i][j]);
}
list.add(temp);
}
return list;
}
leetcode 119 题目链接
杨辉三角的变形题目
public List<Integer> getRow(int rowIndex) {
int[] array = new int[rowIndex + 1];
array[0] = 1;
for (int i = 1; i < rowIndex + 1; i++) {
for (int j = i; j >= 0; j--) {
if (j - 1 >= 0) array[j] += array[j - 1];
if (array[j] == 0) array[j] = 1;
}
}
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < rowIndex + 1; i++) ans.add(array[i]);
return ans;
}
leetcode 121 题目链接
先用了双for暴力法,发现超时了,最后看了官方的题解也有双for
接下来用一次遍历的方法,每次取存储的最小值,用当前值去减去存储在max中即可
public int maxProfit(int[] prices) {
int max=0;
int temp=prices[0];
for(int i=1;i<prices.length;i++){
temp=Math.min(prices[i],temp);
max=Math.max(max,prices[i]-temp);
}
return max;
}
leetcode 122 题目链接
遍历一边求最大值差值 将最大差值分解为每一个小部分相加即可。
public int maxProfit(int[] prices) {
int profit=0;
for(int i=1;i<prices.length;i++){
if(prices[i]-prices[i-1]>0){
profit+=prices[i]-prices[i-1];
}
}
return profit;
}
leetcode 167 题目链接
这题还是很简单的,先暴力算法 时间复杂度O(n^2) 只超过5%。。。
public int[] twoSum(int[] numbers, int target) {
for(int i=0;i<numbers.length;i++){
for(int j=i+1;j<numbers.length;j++){
if(numbers[i]+numbers[j]==target){
i+=1;
j+=1;
return new int[]{i,j};
}
}
}
return null;
}
双指针 只遍历一边,很快。
public int[] twoSum(int[] numbers, int target) {
int i=0;
int j=numbers.length-1;
for(int num:numbers){
if(numbers[i]+numbers[j]>target){
j--;
}else if(numbers[i]+numbers[j]<target){
i++;
}else{
break;
}
}
return new int[]{i+1,j+1};
}
leetcode 169 题目链接
这道题就是返回数组中元素个数超过一般的元素,最开始的思想就是暴力双for循环比较,感觉自己太笨了,什么都是双for,直接将时间复杂度拉满,只超过5%的用户
代码如下(示例):
public int majorityElement(int[] nums) {
if(nums.length==1){
return nums[0];
}
int count=1; int max=0;
for(int i=0;i<nums.length;i++){
for(int j=0;j<nums.length;j++){
if(nums[i]==nums[j]&&i!=j){
count++;
if(count>nums.length>>1){
return nums[j];
}
}
}
count=1;
}
return 0;
}
看完评论后我看到有人两行代码也能过, 最多的数字长度超过长度的一半,返回排好序的中间位置就好了。
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length>>1];
}
}
最后才发现这题是摩尔投票法,核心就是对撞互拼,挺有趣的 ,在评论区看见一个大神写的双百做法,挺巧妙的。
public int majorityElement(int[] nums) {
int count=0;
int last=0;
for(int num:nums){
if(count==0){
last=num;
}
count=count+(last==num?1:-1);
}
return last;
}
leetcode 217
这道题很好写直接排序,遍历就完事了 接近双百的做法
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for(int i=1;i<nums.length;i++){
if(nums[i]==nums[i-1]){
return true;
}
}
return false;
}
可能做数组的题的时候排序不太好,就又写了一种用set的方法
public boolean containsDuplicate(int[] nums) {
Set<Integer> set= new HashSet<>();
for(int i=0;i<nums.length;i++){
if(set.contains(nums[i])){
return true;
}
set.add(nums[i]);
}
return false;
}
但是用set慢了一点。
leetcode 189
这道题开始O(1)空间复杂度不容易想,先用O(n)做,创建一个新数组
public void rotate(int[] nums, int k) {
int []array=new int[nums.length];
for(int i=0;i<nums.length;i++){
array[(i+k)%nums.length]=nums[i];
}
System.arraycopy(array, 0, nums, 0, nums.length);
}
最后看了题解才发现旋转就完事了
public void rotate(int[] nums, int k) {
int n=nums.length;
k%=n;//必须加上,测试用例中会给超出长度的k
func(nums,0,n-1);
func(nums,0,k-1);
func(nums,k,n-1);
}private void func(int [] nums,int left,int right){
while(left<right){
int temp=nums[left];
nums[left]=nums[right];
nums[right]=temp;
left++;
right--;
}
}