携程2019实习生后台开发笔试题 总结

题目1:

给定一个整数的数组,要求将数组中的所有的0元素移动到数组的最后,其他的元素保持原来的顺序。

要求:空间复杂度不能超过O(1)

example:

给定数组[0,2,0,7]转换后应为[2,7,0,0]

输入:

第一行输入一个数组的长度

其他的数为数组中元素。

法1 :

分析:该题目的难点在于将非0的元素移动到数组的前端的时候必须要保持数组原来元素的顺序。我们可以看出0元素是确定的元素,我们可以统计0元素的个数之后,我们其他的元素向前移动的时候就可以将0覆盖。

package com.duoduo.day330;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
	public static void main(String [] args) {
		Scanner sc=new Scanner(System.in);
		int  n=sc.nextInt();         //数组长度
		int [] arr=new int[n];
		for(int i=0;i<n;i++) {
			arr[i]=sc.nextInt();
		}
		moveZeroElement(arr);
	}

	/*将元素0全部移动至最后*/
	private static void moveZeroElement(int[] arr) {
		if(arr==null || arr.length<=0)      //必不可少的输入判断
			return;
		int count=0;   						//统计元素0的个数
		for( int s:arr) {
			if(s==0)
				count++;
		}
		int zeroIndex=arr.length-count;    //新数组0开始的位置
		for(int i=0;i<zeroIndex;i++) {     //在此之前  以非零元素 前移 去替换0元素
			if(arr[i]==0) {                //确定0元素位置
				int j=i+1;
				while(arr[j]==0)           //寻找0元素之后的非零元素 位置
					j++;
				arr[i]=arr[j];             //以 非0元素  覆盖 0元素
				arr[j]=0;
			}
		}
		for(int i=zeroIndex;i<arr.length;i++) {
			arr[i]=0;
		}
		
		System.out.println(Arrays.toString(arr));
		}
}

法2 :暴力做法

import java.util.Arrays;
import java.util.Scanner;
public class Main {
	public static void main(String [] args) {
		Scanner sc=new Scanner(System.in);
		int  n=sc.nextInt();         //数组长度
		int [] arr=new int[n];
		for(int i=0;i<n;i++) {
			arr[i]=sc.nextInt();
		}
		moveZeroElement(arr);
	}

	public static void moveZeroElement(int [] arr) {
		if(arr==null || arr.length<=0)
			return;
		int count=0;
		for(int s:arr) {                               //0元素的个数
			if(s==0)
				count++;
		}
		for(int i=0;i<arr.length;i++) {
			if(arr[i]!=0)                        //打印全部非0元素
				System.out.print(arr[i]+" ");
		}
		
		for(int i=0;i<count;i++) {               //再打印剩下的0元素 到数组末尾
			System.out.print("0 ");
		}
		System.out.println();
	}

法3 :(喜欢最后一个的思路)

	/*将非0元素前移  剩下的补0即可*/
	public static void moveZeroElement(int[] arr) {
		if(arr==null || arr.length<=0)
			return;
		int len=arr.length;
		int count=0;
		for(int i=0;i<len;i++) {
			if(arr[i]!=0) 
				arr[count++]=arr[i];    //非0元素从开头计数储存
		}
		
		for(int i=count;i<len;i++) {            //非0元素开始到数组结束补0
			arr[i]=0;
		}
		
	}

题目2 : 有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。 

给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于300。

方法1 :一步到位  

package com.duoduo.day330;
import java.util.Scanner;


public class Main2 {
	public static void main(String [] args) {
		Scanner sc=new Scanner(System.in);
		String str=sc.nextLine();        //读 取一行的字符串 并自动换行
		String[] str1=str.split(" ");    //切割字符串--数组
		int N=str1.length;               //矩阵长度N
		int[][] arr=new int[N][N];       //新建数组
		for(int i=0;i<N;i++) {
			 arr[0][i]=Integer.valueOf(str1[i]);    
		}
		
		for(int i=1;i<N;i++) {
			String strr=sc.nextLine();  
			String[] str2=strr.split(" ");
			for(int j=0;j<N;j++) {
				arr[i][j]=Integer.valueOf(str2[j]);
			}
		}
		
		int[][] temp=rotate(arr); 
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<N;j++) {
				System.out.print(temp[i][j]+" ");
			}
			System.out.println();
		}
		
	}


	/*一步到位 增加辅助数组  arr[i][j] ---->arr[j][k]  k=len-1 开始k--*/
	private static int[][] rotate(int[][] arr) {
		if(arr==null)                        //判断输入合法
			return null;
		int len1=arr.length;
		int len2=arr[0].length;
		int [][]temp=new int [len2][len1];
		int k=len2-1;
		for(int i=0;i<len1;i++,k--) {
			for(int j=0;j<len2;j++) {
				temp[j][k]=arr[i][j];
			}
		}
		return temp;
	}
}



方法2:先转置再逆序


package com.duoduo.day330;
import java.util.Scanner;

public class Main2 {
	public static void main(String [] args) {
		Scanner sc=new Scanner(System.in);
//		if(sc.next()==" ")   //增加边界情况
//			return;
		String str=sc.nextLine();        //读 取一行的字符串 并自动换行
		String[] str1=str.split(" ");    //切割字符串--数组
		int N=str1.length;               //矩阵长度N
		int[][] arr=new int[N][N];       //新建数组
		for(int i=0;i<N;i++) {
			 arr[0][i]=Integer.valueOf(str1[i]);    
		}
		
		for(int i=1;i<N;i++) {
			String strr=sc.nextLine();  
			String[] str2=strr.split(" ");
			for(int j=0;j<N;j++) {
				arr[i][j]=Integer.valueOf(str2[j]);
			}
		}
		
		rotate(arr); 
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<N;j++) {
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
		
	}

	/*先转置 再逆序   */
	private static void rotate(int[][] arr) {
		if(arr==null)                            //判断输入合法
			return ;
		int len=arr.length;
		int len2=arr[0].length;
		//转置  沿主对角线对称位置上的元素进行交换   
		//在原数组上操作 即交换  否则 辅助数组 arr[i][j]=a[j][i] 
		for(int i=0;i<len;i++) {
			for(int j=0;j<i;j++) {            //半个二维矩阵进行交换
				int temp=arr[i][j];
				arr[i][j]=arr[j][i];
				arr[j][i]=temp;
			}
		}
		
		//逆序   对一维数组而言,将每一行第i个元素与第N-i-1个元素进行交换
		for(int i=0;i<len;i++){
			for(int j=0;j<len2/2;j++) { 
				int temp=arr[i][j];
				arr[i][j]=arr[i][len2-j-1];
				arr[i][len2-j-1]=temp;
			}
		}
	}
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
携程的Java校招笔试题主要考察对Java语言的基础知识和应用能力的掌握。下面我将用300字中文回答一道携程Java校招笔试题。 题目描述:有一个包含N个元素的整型数组,数组中的元素可正可负。编写一个函数,返回数组中所包含元素的最大连续子数组的和。 解题思路:这是一道求最大连续子数组和的经典问题,可以使用动态规划的思想解决。 首先,我们定义两个变量max和currentSum,分别用于保存当前的最大连续子数组和和当前元素的和。初始时,将max和currentSum都设置为数组中的第一个元素。 然后,我们从数组的第二个元素开始遍历。对于每个元素,我们将其与之前的currentSum相加,并与该元素本身进行比较。如果大于当前元素,则更新currentSum为这个和,否则,将currentSum设置为当前元素。 同时,我们还需要将currentSum与max进行比较,如果大于max,则更新max为currentSum。这样,每次遍历的时候都会更新最大连续子数组和。 最后,当遍历完整个数组后,max中保存的就是最大连续子数组的和。将其返回即可。 代码示例: ```java public int maxSubArraySum(int[] nums) { int max = nums[0]; int currentSum = nums[0]; for (int i = 1; i < nums.length; i++) { currentSum = Math.max(currentSum + nums[i], nums[i]); max = Math.max(max, currentSum); } return max; } ``` 这个函数的时间复杂度是O(N),其中N是数组的长度。 通过以上的解题思路和示例代码,我们可以在面试中灵活应用,解决类似的最大连续子数组和的问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值