Java训练题10

一、选择题

1、数组常用的两种基本操作是 (C )
A. 建立与删除
B. 删除与查找
C. 查找与修改
D. 插入与索引
答案解析:C
数组指的就是一组相关类型的变量集合,数组的访问通过索引完成。
所以数组的查找和修改效率比较高。
2、线性表的逻辑顺序与物理顺序总是一致的 (B )
A. 是
B. 否
答案解析:B
这句话错误。
比如数组和链表都属于线性表。
但是链表是一种物理存储结构上非连续存储结构
3、定义了一维 int 型数组 a[10] 后,下面错误的引用是( C)
A. a[0] = 1;
B. a[0] = 5*2;
C. a[10] = 2;
D. a[1] = a[2] * a[0];
答案解析:C
a[10]下标越界了,会报异常java.lang.ArrayIndexOutOfBoundsException
4、从一个长度为n的数组中删除第i个元素(1≤i≤n)时,需向前移动()个元素 (A )
A. n-i
B. n-i+1
C. n-i-1
D. i
答案解析:A
数组第i个元素后还有n-i个元素;
所以删除数组第i个元素,需要向前移动n-i个元素
5、下列关于链表的描述中正确的是【多选】(A B C )
A. 链表由头指针唯一确定,单链表可以用头指针的名字来命名
B. 线性链表的存储空间不一定连续,并且各元素的存储顺序是任意的
C. 链表的插入删除不需要移动元素,可以只改变指针
D. 链表可随机访问任一元素
答案解析:A B C
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
它由头指针唯一确定,其中每一个链表结点的链接是通过指针来实现的;
由于链表是通过指针来访问的,一个结点最多只存放它前面一个结点的指针和后面一个结点的指针,所以链表无法随机访问元素。
D项是错误的

二、编程题

1、从链表中删去总和值为零的连续节点
给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0 的连续节点组成的序列,直到不存在这样的序列为止。删除完毕后,请你返回最终结果链表的头节点。OJ链接

示例1:
输入:head = [1,2,-3,3,1]
输出:[3,1]
提示:答案 [1,2,1] 也是正确的。
示例2:
输入:head = [1,2,3,-3,4]
输出:[1,2,4]

【解题思路】:
定义一个值为 0 的虚拟头节点,当做原链表新的头节点,即 dummyHead.next = head;定义一个 pre 指针指向虚拟头节点作为原链表头节点的前驱节点(方便进行删除操作)。
定义一个指针 p 指向 pre 指向节点的后一个节点(开始时,p 指向原链表的头节点);然后 p 指针开始遍历链表,每遍历一个节点就将该节点值与之前节点值总和进行相加得到新的 sum:
若 sum == 0,则需要进行删除(将 pre 指针和 p 指针指向节点(包括 p 指针指向的节点)中间的节点删除),即pre.next = p.next 然后直接退出循环:
若此时 p 指针已经走到了链表的末尾,则令 pre 指针后移一位并且 p 指向 pre 指向节点的下一节点重新进行判断以及删除;
若此时 p 指针没有走到链表的末尾,则令 pre 指针不动,p 指针继续从 pre 指针指向节点的下一节点开始遍历链表并进行比较和删除操作;
若 sum != 0,则 p 指针继续后移,继续对下一节点进行判断,直到找到使 sum 值为 0 的节点或遍历到链表的结尾为止。
注意:只有当 p 指针指向链表末尾时,pre 指针才后移;否则,则 pre 指针不动,令 p 指针在删除后的链表中继续从头开始遍历。
if (p == null) pre = pre.next;
示例:head = [0, 1, -1] dummyHead = [0, 0, 1, -1]
若没有这个判断,则只要跳出循环就将 pre 指针后移一位,则会出现问题。 开始时,pre 指向第一个 0 并且 p指向第二个 0,此时 sum = 0 则进行删除并且 pre = pre.next,此时 dummyHead = [0, 1, -1]; pre 指向 1 并且 p 指向 -1,此时 sum = -1,p 继续后移为 null 结束循环,最后会输出 [1, -1] 答案错误。
若有这个判断,当将 p 指针指向的 0 删除后,p 没有指向链表末尾 pre 指针不进行移动,此时 dummyHead =[0, 1, -1]; pre 指针仍指向 0,此时 p 指针指向 1,sum = 1 则 p 指针后移;p 指向 -1,此时 sum = 0, 则进行删除操作,此时 dummyHead = [0] 结束,返回dummyHead.next 即可。

class Solution {
    public ListNode removeZeroSumSublists(ListNode head) {
        if(head==null){
            return head;
        }
        ListNode dummyHead=new ListNode(0);
        dummyHead.next=head;
        ListNode pre=dummyHead;
        while(pre!=null){
            ListNode p=pre.next;
            int sum=0;
            while(p!=null){
                sum=sum+p.val;
                if(sum==0){
                    pre.next=p.next;
                    break;
                }else{
                    p=p.next;
                }
            }
            if(p==null){
                pre=pre.next;
            }
        }
         return dummyHead.next;
    }
}

2、两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。OJ链接

示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]

【解题思路】:
将两个链表看成是相同长度的进行遍历,如果一个链表较短则在前面补 0,比如 987 + 23 = 987 + 023 = 1010 每一位计算的同时需要考虑上一位的进位问题,而当前位计算结束后同样需要更新进位值 如果两个链表全部遍历完毕后,进位值为 1,则在新链表最前方添加节点 1 小技巧:对于链表问题,返回结果为头结点时,通常需要先初始化一个预先指针 pre,该指针的下一个节点指向真正的头结点head。使用预先指针的目的在于链表初始化时无可用节点值,而且链表构造过程需要指针移动,进而会导致头指针丢失,无法返回结果。

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       ListNode pre=new ListNode(0);
       ListNode cur=pre;
       int carry=0;
       while(l1!=null||l2!=null){
           int x=l1==null?0:l1.val;
           int y=l2==null?0:l2.val;
           int sum=x+y+carry;
           carry=sum/10;
           sum=sum%10;
           cur.next=new ListNode(sum);
           cur=cur.next;
           if(l1!=null){
               l1=l1.next;
           }
           if(l2!=null){
               l2=l2.next;
           }
       }
           if(carry==1){
               cur.next=new ListNode(carry);
           }
        return pre.next;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 编写一个 Java 程序,在控制台输出“Hello World!” ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } ``` 2. 编写一个 Java 程序,求一个整数数组中的最大值和最小值 ```java public class MaxMin { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; int max = arr[0]; int min = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } if (arr[i] < min) { min = arr[i]; } } System.out.println("最大值:" + max); System.out.println("最小值:" + min); } } ``` 3. 编写一个 Java 程序,计算从 1 到 100 的所有整数的和 ```java public class Sum { public static void main(String[] args) { int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } System.out.println("总和:" + sum); } } ``` 4. 编写一个 Java 程序,判断一个整数是否为质数 ```java public class PrimeNumber { public static void main(String[] args) { int num = 7; boolean isPrime = true; for (int i = 2; i < num; i++) { if (num % i == 0) { isPrime = false; break; } } if (isPrime) { System.out.println(num + "是质数"); } else { System.out.println(num + "不是质数"); } } } ``` 5. 编写一个 Java 程序,判断一个字符串是否为回文字符串 ```java public class Palindrome { public static void main(String[] args) { String str = "level"; boolean isPalindrome = true; for (int i = 0; i < str.length() / 2; i++) { if (str.charAt(i) != str.charAt(str.length() - 1 - i)) { isPalindrome = false; break; } } if (isPalindrome) { System.out.println(str + "是回文字符串"); } else { System.out.println(str + "不是回文字符串"); } } } ``` 6. 编写一个 Java 程序,将一个字符串中的所有空格替换为“%20” ```java public class ReplaceSpace { public static void main(String[] args) { String str = "Hello World"; String newStr = str.replaceAll(" ", "%20"); System.out.println(newStr); } } ``` 7. 编写一个 Java 程序,将一个字符串反转 ```java public class ReverseString { public static void main(String[] args) { String str = "abcdefg"; StringBuilder sb = new StringBuilder(str); sb.reverse(); System.out.println(sb.toString()); } } ``` 8. 编写一个 Java 程序,将一个数组中的元素顺序颠倒 ```java public class ReverseArray { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; int[] newArr = new int[arr.length]; for (int i = 0; i < arr.length; i++) { newArr[arr.length - 1 - i] = arr[i]; } System.out.println(Arrays.toString(newArr)); } } ``` 9. 编写一个 Java 程序,输出九九乘法表 ```java public class MultiplicationTable { public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j + "×" + i + "=" + j * i + "\t"); } System.out.println(); } } } ``` 10. 编写一个 Java 程序,求斐波那契数列中的第 n 项 ```java public class Fibonacci { public static void main(String[] args) { int n = 7; int[] arr = new int[n]; arr[0] = 1; arr[1] = 1; for (int i = 2; i < arr.length; i++) { arr[i] = arr[i - 1] + arr[i - 2]; } System.out.println("第" + n + "项:" + arr[n - 1]); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值