阿翰刷题系列 之 入门 2/14

这篇博客介绍了LeetCode中的两道题目:有序数组的平方(977)和旋转数组(189)。博主提供了多种解法,包括直接平方后排序、双指针法和环形替换等,详细解释了每种方法的思路和实现过程,展示了Java代码实现。
摘要由CSDN通过智能技术生成

 第一题 LeetCode 278

977. 有序数组的平方icon-default.png?t=L892https://leetcode-cn.com/problems/squares-of-a-sorted-array/

三种解法:

  • 第一种 直接平方后排序
  • 第二种 找到正负临界点,再双指针,从中间往两边,存入结果数组。存入的过程先考虑有一边走到头的情况,再考虑比较,类似于归并。
  • 第三种 从两边往中间比较,挑出来大的倒着存入结果数组
package Day14.no2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

/**
 * @author ahan
 * @create_time 2021-09-27-2:20 下午
 */
public class _977 {
    public static void main(String[] args) {
        int[] nums = {-7,-3,2,3,11};
        _977 soulution = new _977();
        int[] ints = soulution.sortedSquares(nums); 
        for (int i = 0; i < ints.length; i++) {
            System.out.print(ints[i] + " ");
        }
    }
    public int[] sortedSquares(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
//            nums[i] = nums[i] * nums[i];
            nums[i] = (int) Math.pow(nums[i], 2);
        }
        return Arrays.stream(nums).sorted().toArray();
    }
    public int[] sortedSquares2(int[] nums) {
        int[] res = new int[nums.length];
        for (int i = 0; i < nums.length; ++i) {
            res[i] = nums[i] * nums[i];
        }
        Arrays.sort(res);
        return res;
    }
    public int[] sortedSquares3(int[] nums) {
        int n = nums.length;
        int negative = -1;
//        找到临界点
        for (int i = 0; i < n; ++i) {
            if (nums[i] < 0) {
                negative = i;
            } else {
                break;
            }
        }
        int[] res = new int[n];
        int index = 0, i = negative, j = negative + 1;
        while (i >= 0 || j < n) {
//            先判断是不是两边有一边走完了的两种情况
            if (i < 0) {
                res[index] = nums[j] * nums[j];
                ++j;
            } else if (j == n) {
                res[index] = nums[i] * nums[i];
                --i;
            } else if (nums [i] * nums[i] < nums[j] * nums[j]) {
                res[index] = nums[i] * nums[i];
                --i;
            } else {
                res[index] = nums[j] * nums[j];
                ++j;
            }
            ++index;
        }
        return res;
    }

    public int[] sortedSquares4(int[] nums) {
        int[] res = new int[nums.length];
        int left = 0;
        int right = nums.length - 1;
        int i = right;
        while(left <= right){
            if(- nums[left] > nums[right]){
                res[i] = nums[left] * nums[left];
                left += 1;
            } else{
                res[i] = nums[right] * nums[right];
                right -= 1;
            }
            i--;
        }
        return res;
    }
}

第二题 LeetCode  189. 旋转数组icon-default.png?t=L892https://leetcode-cn.com/problems/rotate-array/

四种解法:

第一种

数组末尾元素和前面所有元素,从第一个开始到倒数第二个,挨个利用一个临时变量交换。循环k次。会超时。。。

第二种 反转

        如 1234567 反转后为7654321 

        根据k=3, 分为两部分 765 4321 

        再 分别反转, 567 1234 over~

第三种 环形数组

        count 为 k和n的最大公约数 即圈数  (类似辗转相除法)

public int gcd(int x, int y) {
        return y > 0 ? gcd(y, x % y) : x;
    }

        从start = 0,current = start位置开始,利用一个临时变量 prev 存上一个位置的值,和 next = (current + k) % n 位置的值交换,然后再把 next赋值为current。循环构造为do while(start !=current)

第四种

        开辟额外的数组存放原数组(复制原数组)news,作为结果的nums数组中的 nums[i],在news数组中找到对应的数组元素即 news[(i+k)%n] 做交换,一一映射。

package Day14.no2;

/**
 * @author ahan
 * @create_time 2021-09-27-3:39 下午
 */
public class _189 {
    public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,6,7};
//        567 1234
        _189 s = new _189();
        s.rotate_1(nums, 5);
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i] + " ");
        }
        System.out.println("\n");
        int[] nums2 = {1,2,3,4,5,6,7};
        s.rotate_reverse(nums2, 3);
        for (int i = 0; i < nums2.length; i++) {
            System.out.print(nums2[i] + " ");
        }
        System.out.println("\n");
        int[] nums3 = {1,2,3,4,5,6,7};
        s.rotate_3(nums3, 4);
        for (int i = 0; i < nums3.length; i++) {
            System.out.print(nums3[i] + " ");
        }
        System.out.println("\n");
    }
    public void rotate_1(int[] nums, int k) {
        int n = nums.length;
        int[] newArr = new int[n];
        for (int i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i];
        }
        System.arraycopy(newArr, 0, nums, 0, n);
    }
//    反转
    public void rotate_reverse(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
//    环形替换
    public void rotate_3(int[] nums, int k) {
        int n = nums.length;
        k = k % n;
        int count = gcd(k, n);
        for (int start = 0; start < count; ++start) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % n;

                int temp = nums[next];
                nums[next] = prev;
                prev = temp;

                current = next;
            } while (start != current);
        }
    }
    public int gcd(int x, int y) {
        return y > 0 ? gcd(y, x % y) : x;
    }

    public void rotate_me_nowork(int[] nums, int k) {
        int left = 0;
        int right = nums.length - 1;

        for(int j = right, t = 0;t < k;t++){
            while(left < right){
                chang(nums, j, left);
                left+=1;
            }
            left = 0;
        }
    }
    private void chang(int[] nums, int a , int b) {
//        第34个测试用例not pass
//        nums[a] = nums[a] + nums[b];
//        nums[b] = nums[a] - nums[b];
//        nums[a] = nums[a] - nums[b];
//        第37个测试用例not pass
//        nums[b] = (nums[a] + nums[b]) - (nums[a] = nums[b]);
//        第34个测试用例not pass
//        nums[a] = nums[a]^nums[b];  //赋值表达式先不动
//        nums[b] = nums[a]^nums[b];  //b = (a^b)^b;  b值发生的改变为a的值;
//        nums[a] = nums[b]^nums[a];  //a = (a^b)^a;  a值也发生了改变;
//        第37个测试用例not pass
        int  temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
    }
    public void rotate_4(int[] nums, int k) {
        int n = nums.length;

        int[] news = Arrays.copyOf(nums,n);

        for (int i = 0; i < n; i++) {
            nums[(i+k)%n] = news[i];
        }
    } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值