LeetCode(力扣)经典算法题-day01-java语言实现

问题描述:

You may have been using Java for a while. Do you think a simple Java array question
can be a challenge? Let’s use the following problem to test.
Problem: Rotate an array of n elements to the right by k steps. For example, with n
= 7 and k = 3 , the array [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] is rotated to [ 5 , 6 , 7 , 1 , 2 , 3 , 4 ].
How many different ways do you know to solve this problem?

您可能已经使用Java有一段时间了。你认为一个简单的Java数组问题会是一个挑战吗?让我们使用以下问题来进行测试。问题:通过k步,向右旋转n个元素的数组。例如,使用n = 7和k = 3,数组[1,2,3,4,5,6,7]被旋转到[5,6,7,1,2,3,4]。你知道有多少种不同的方法来解决这个问题?

我们可以写出三种难易不同,时间空间复杂度的算法来解决

方法一:

package LeetCode.demo01;


/**
 * question01
 *问题:通过k步,向右旋转n个元素的数组。
 * 例如,使用n = 7和k = 3,数组[1,2,3,4,5,6,7]被旋转到[5,6,7,1,2,3,4]。
 * 你知道有多少种不同的方法来解决这个问题?
 *
 * 1.简单数组方法 (时间空间复杂度都为O(n))
 * @author 张子杰
 */
import java.util.Scanner;

public class Demo01 {
//主函数用来测试
    public static void main(String[] args) {
//        int[] nums={5,6,7,1,2,3,4};
//        int k=3;
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入数组的长度:");
        int n=sc.nextInt();
        System.out.println("请输入数组元素:");
        int[] nums=new int[n];
        for (int i = 0; i < nums.length; i++) {
            nums[i]=sc.nextInt();
        }
        System.out.println("请输入要旋转步数:");
        int k=sc.nextInt();
        rotate(nums,k);
    }
//解决方法,其实正确的解就是这个rotate方法去掉最后的打印,加上只是为了测试
    public static void rotate(int[] nums, int k) {
        if (k>nums.length) {
            k=k%nums.length;
        }

        int[] result=new int[nums.length];

        for (int i = 0; i < k ; i++) {

            result[i]=nums[nums.length-k+i];
        }
        int j=0;
        for (int i=k; i< nums.length; i++ ) {
            result[i]=nums[j];
            j++;
        }
        System.arraycopy(result,0,nums,0,nums.length);

        for (int i = 0; i < nums.length ; i++) {
            System.out.print(nums[i]+" ");
        }

    }

}

这个方法用到了一个System.arraycopy()函数

它的具体用法:

public class SystemArrayCopy {

    public static void main(String[] args) {
        int[] src = {1, 2, 3, 4};
        int[] dest = new int[5];
        System.arraycopy(src, 0, dest, 1, 4);

        for (Object o : dest) {
            System.out.println(o);
        }
    }
}
/*结果:
0 1 2 3 4
*/
/*
src = |1|2|3|4|
dest = |0|0|0|0|0|
执行System.arraycopy(src, 0, dest, 1, 4);时
第一步:从源数组(src)中,从下标0开始取,取4个,也就是src[0]-src[3],即1 2 3 4四个数
第二步:把取出的数,按顺序,存放到目标数组(dest)中,从下标1开始存,存4个,
也就是dest[1]-dest[4]
所以数组dest为:|0|1|2|3|4|
*/

方法二

package LeetCode.demo01;

/**
 * question01
 *问题:通过k步,向右旋转n个元素的数组。
 * 例如,使用n = 7和k = 3,数组[1,2,3,4,5,6,7]被旋转到[5,6,7,1,2,3,4]。
 * 你知道有多少种不同的方法来解决这个问题?
 *
 * 2. 空间复杂度为O(1)的方法
 *类似冒泡排序  将最后一个元素冒泡排到最前面 重复n次,n为需要翻转的个数(次数)即可得到
 * @author 张子杰
 */
public class Demo02 {
    public static void main(String[] args) throws IllegalAccessException {
        int[] nums={3,4,5,6,1,2};
        int k=2;
        rotate(nums,k);
    }
    public static void rotate(int[] arr,int order) throws IllegalAccessException {
        if (order > arr.length || order < 0){
            throw new IllegalAccessException("illegal argument!");
        }

        int temp;
        for (int i = 0; i < order; i++) {
            for (int j = arr.length-1; j >0 ; j--) {
                temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
            }
        }
        for (int i = 0; i < arr.length ; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}

方法三

package LeetCode.demo01;

/**
 * question01
 *问题:通过k步,向右旋转n个元素的数组。
 * 例如,使用n = 7和k = 3,数组[1,2,3,4,5,6,7]被旋转到[5,6,7,1,2,3,4]。
 * 你知道有多少种不同的方法来解决这个问题?
 *
 * 3.最优解  时间复杂度为O(1)  空间复杂度为O(n) 的算法
 * 步骤:
 *1.将数组分成两部分:1,2,3,4和5,6。
 *2.旋转第一部分得到:4、3、2、1、5、6 。
 *3.旋转第二部分:4、3、2、1、6、5 。
 *4.旋转整个阵列:5、6、1、2、3、4
 * @author 张子杰
 */
public class Demo03 {
    public static void main(String[] args) {
        int[] nums={1,2,3,4,5,6};
        int k=2;
        rotate(nums,k);
    }

    public static void rotate(int[] arr, int order) {
        order = order % arr.length;
        if (arr == null || order < 0) {
            throw new IllegalArgumentException("Illegal argument!");
        }
       //length of first part
        int a = arr.length - order;
        reverse(arr, 0, a - 1);
        reverse(arr, a, arr.length - 1);
        reverse(arr, 0, arr.length - 1);

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

    public static void reverse(int[] arr, int left, int right) {
        if (arr == null || arr.length == 1) {
            return;
        }

        while (left < right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值