牛客网刷题(数组数+1、合并有序链表、链表右转)

题目一描述:
给出用数字数组表示的一个非负整数,请对该整数加1。
题目一分析:
题目的意思是,将一个多位数按位置分开放置在数组中,每个位置上的数字表示该多位数的某一位数。
例如:569,使用int[] arr = {5,6,9};表示
代码如下:

public class Solution {
    public int[] plusOne(int[] digits) {
    	  //该数组的长度,从后向前遍历数组第一个不为9的数字+1
         int left = digits.length-1;
         //从后向前指针移动,遇到9将对应的数字改为0,遇到不为9的数字,直接+1
			while(digits[left]==9) {
				if(left==0) break;
				digits[left]=0;
				left--;
			}
			//第一个不为9的数
			if(digits[left]<=9) digits[left]=digits[left]+1;
			//如果每个数字都为9,则数组长度+1,最高位置为1
			int[] arr=new int[digits.length+1];
			arr[0]=1;
			//返回结果有两种,一个是原数组长度(例如:366,499),一个是原长度+1(例如:999,99等)
		return (left==0&&digits[left]>9)?arr:digits;
    }
}

题目二描述:
将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。
题目二分析:
将有序链表合并,结果返回有序链表,这个题目之前应该刷过。基本思路是利用插入法类似的方法使用两个指针指向两个有序链表并且进行组合。
代码如下:

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
         if(l1 == null && l2 == null) return null;
		 if(l1 == null) return l2;
		 if(l2 == null) return l1;
		 //两个指针指向两个有序的链表,另外一个为新的链表
		 ListNode head = new ListNode(-1);
		 ListNode left = l1;
		 ListNode right = l2;
		 ListNode index = head;
		 //两条链表都有值,进行插入新链表操作
		 while(left != null&&right != null) {
			 if(left.val < right.val) {
				 index.next = left;
				 left = left.next;
			 }else {
				 index.next=right;
				 right = right.next;
			 }
			 index = index.next;
		 }
		 //left指针指向的链表没有插入完
		 while(left != null) {
			 index.next=left;
			 left=left.next;
			 index=index.next;
		 }
		 //right指针指向的链表没有插入完成
		 while(right != null) {
			 index.next=right;
			 right=right.next;
			 index=index.next;
		 }
		 //返回新链表
		 return head.next;
    }
}

题目二描述:
将给定的链表向右转动k个位置,k是非负数。
例如:
给定1->2->3->4->5->null , k=2,
返回4->5->1->2->3->null。
题目二分析:
根据题目似乎并不能判断真正地意思,测试几个case后就知道,相当于一个有环的链表进行向右移动。当n小于链表的长度时,可以使用一个窗来进行移动;当n大于链表的长度,多余的数相当于一个窗进行移动。例如:
1,2,3,4,5。k=2,可以定义一个窗大小为3,就是两个指针相差为3,因为必须前一个指针指向反转窗中的前一个元素,否则链表就不能获取元素。
代码如下:

public class Solution {
    public ListNode rotateRight(ListNode head, int n) {
        if(n == 0 || head == null) return head;
        //定义窗的两个指针
		 ListNode left = head; 
		 ListNode right = head;
		 //使用i来记录链表的长度
         int i;
		  for(i=1;i<=n;i++) {
		  //当n很大时,链表指向空还没有到n就将右边的窗指向左边,相当于循环向右移动一个链表的长度,所有元素依旧在其位置
			 if(right.next == null) {
				 right=left;
				 continue;
			}
			 right = right.next;
		 }
		 //固定窗大小后,使其框住最后的元素
		 while(right.next!=null) {
			 left=left.next;
			 right=right.next;
		 }
		 //最右的指针指向头部,最左的指针指向空,需要保留左边指针的下一个元素,为新的链表头部
		 right.next = head;
		 right=left.next;
		 left.next = null;
		 return right;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值