真题练习——幸运数——利用了链表,补充了知识点

一、题目
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。
首先从1开始写出自然数1,2,3,4,5,6,… 1 就是第一个幸运数。 我们从2这个数开始。把所有序号能被2整除的项删除,变为:
1 _ 3 _ 5 _ 7 _ 9 …
把它们缩紧,重新记序,为: 1 3 5 7 9 … 。
这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。
注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, …
此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,…)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, …
本题要求:
输入两个正整数m n, 用空格分开 (m < n < 1000*1000)程序输出 位于m和n之间的幸运数的个数(不包含m和n)。
例如:
用户输入:1 20
程序输出:5
例如:
用户输入:30 69
程序输出:8

二、心得
像这种不断地需要添加修改的,并且修改前后的顺序不发生改变的要想到用链表来存贮

三、难点
Java自带的链表库当用remove一个数时,他会自动向前移动,因此,当删除的位置为3,6,9时,删除3后,原本在6的位置,会向前移动变为5的位置,删除5后,原本在9的位置会向前移动到7的位置。解决方法,可以如下:
每次删除一个数就记录删除的个数,然后下一个位置就等于被3整除的位置-已经删除的个数即可。

四、知识点
Java链表的基本操作实现:

1.链表 import java.util.LinkedList
(1)链表的优点
LinkedList :是链表结构,增加和删除速度快,就像佛珠。当你需要通过循环迭代来访问列表中的某些元素或者需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作可以用LinkedList

(2)链表的基本操作函数
https://blog.csdn.net/m0_46521785/article/details/113667733
在这里插入图片描述
(3)注意,遍历链表的方法有一下几种:

①迭代器遍历

import java.util.Iterator;
import java.util.LinkedList;

public class Main{
    public static void main(){
        LinkedList<String> list=new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> iterator=list.iterator();
        while(i.hasNext()){
        String t=i.Next();
        }
    }
}
 

②for循环遍历

import java.util.Iterator;
import java.util.LinkedList;

public class Main{
    public static void main(){
        LinkedList<String> list=new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> iterator=list.iterator();
        for(int i=1;i<=list.size();i++){
        String t=list.get(i);
        }
    }
}
 

③for循环简化遍历(本也是用迭代器)

import java.util.Iterator;
import java.util.LinkedList;

public class Main{
    public static void main(){
        LinkedList<String> list=new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator<String> iterator=list.iterator();
        for(String i:list){
        String t=i;//就是将List的元素取出来存入i
        }
    }
}
 

三种遍历方式,①③方式的效率比二方式效率高100倍,因此要常用①③方式遍历,少用②,迭代器还可以用于Vector遍历,Hsahmap也可以

(4)LinkedList的使用示例

/**
 * @author GongchuangSu
 * @since 2016.05.11
 */
import java.util.Iterator;
import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] srgs){
        LinkedList<Integer> linkedList = new LinkedList<>();

        /************************** 基本操作 ************************/
        linkedList.addFirst(0);    // 添加元素到列表开头
        linkedList.add(1);         // 在列表结尾添加元素
        linkedList.add(2,2);       // 在指定位置添加元素
        linkedList.addLast(3);     // 添加元素到列表结尾

        System.out.println("LinkedList: " + linkedList);

        System.out.println("getFirst(): " + linkedList.getFirst());       // 返回此列表的第一个元素
        System.out.println("getLast(): " + linkedList.getLast());         // 返回此列表的最后一个元素       
        System.out.println("removeFirst(): " + linkedList.removeFirst()); // 移除并返回此列表的第一个元素     
        System.out.println("removeLast(): " + linkedList.removeLast());   // 移除并返回此列表的最后一个元素
        System.out.println("After remove:" + linkedList);                   
        System.out.println("contains(1) is :" + linkedList.contains(1));  // 判断此列表包含指定元素,如果是,则返回true    
        System.out.println("size is : " + linkedList.size());             // 返回此列表的元素个数

        /************************** 位置访问操作 ************************/
        System.out.println("-----------------------------------------");
        linkedList.set(1, 3);                                             // 将此列表中指定位置的元素替换为指定的元素
        System.out.println("After set(1, 3):" + linkedList);  
        System.out.println("get(1): " + linkedList.get(1));               // 返回此列表中指定位置处的元素

        /************************** Search操作  ************************/
        System.out.println("-----------------------------------------");
        linkedList.add(3);
        System.out.println("indexOf(3): " + linkedList.indexOf(3));        // 返回此列表中首次出现的指定元素的索引
        System.out.println("lastIndexOf(3): " + linkedList.lastIndexOf(3));// 返回此列表中最后出现的指定元素的索引

        /************************** Queue操作   ************************/
        System.out.println("-----------------------------------------");
        System.out.println("peek(): " + linkedList.peek());                // 获取但不移除此列表的头
        System.out.println("element(): " + linkedList.element());          // 获取但不移除此列表的头
        linkedList.poll();                                                 // 获取并移除此列表的头
        System.out.println("After poll():" + linkedList);
        linkedList.remove();
        System.out.println("After remove():" + linkedList);                // 获取并移除此列表的头
        linkedList.offer(4);
        System.out.println("After offer(4):" + linkedList);                // 将指定元素添加到此列表的末尾  

        /************************** Deque操作   ************************/
        System.out.println("-----------------------------------------");
        linkedList.offerFirst(2);                                          // 在此列表的开头插入指定的元素
        System.out.println("After offerFirst(2):" + linkedList);
        linkedList.offerLast(5);                                           // 在此列表末尾插入指定的元素
        System.out.println("After offerLast(5):" + linkedList);
        System.out.println("peekFirst(): " + linkedList.peekFirst());      // 获取但不移除此列表的第一个元素
        System.out.println("peekLast(): " + linkedList.peekLast());        // 获取但不移除此列表的第一个元素
        linkedList.pollFirst();                                            // 获取并移除此列表的第一个元素
        System.out.println("After pollFirst():" + linkedList);
        linkedList.pollLast();                                             // 获取并移除此列表的最后一个元素
        System.out.println("After pollLast():" + linkedList);
        linkedList.push(2);                                                // 将元素推入此列表所表示的堆栈(插入到列表的头)
        System.out.println("After push(2):" + linkedList);
        linkedList.pop();                                                  // 从此列表所表示的堆栈处弹出一个元素(获取并移除列表第一个元素)
        System.out.println("After pop():" + linkedList);
        linkedList.add(3);
        linkedList.removeFirstOccurrence(3);                               // 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表)
        System.out.println("After removeFirstOccurrence(3):" + linkedList);
        linkedList.removeLastOccurrence(3);                                // 从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表)
        System.out.println("After removeFirstOccurrence(3):" + linkedList);

        /************************** 遍历操作   ************************/
        System.out.println("-----------------------------------------");
        linkedList.clear();
        for(int i = 0; i < 100000; i++){
            linkedList.add(i);
        }
        // 迭代器遍历
        long start = System.currentTimeMillis();
        Iterator<Integer> iterator = linkedList.iterator();
        while(iterator.hasNext()){
            iterator.next();
        }
        long end = System.currentTimeMillis();
        System.out.println("Iterator:" + (end - start) +" ms");

        // 顺序遍历(随机遍历)
        start = System.currentTimeMillis();
        for(int i = 0; i < linkedList.size(); i++){
            linkedList.get(i);
        }
        end = System.currentTimeMillis();
        System.out.println("for:" + (end - start) +" ms");

        // 另一种for循环遍历
        start = System.currentTimeMillis();
        for(Integer i : linkedList);
        end = System.currentTimeMillis();
        System.out.println("for2:" + (end - start) +" ms");

        //  通过pollFirst()或pollLast()来遍历LinkedList
        LinkedList<Integer> temp1 = new LinkedList<>();
        temp1.addAll(linkedList);
        start = System.currentTimeMillis();
        while(temp1.size() != 0){
            temp1.pollFirst();
        }
        end = System.currentTimeMillis();
        System.out.println("pollFirst()或pollLast():" + (end - start) +" ms");

        // 通过removeFirst()或removeLast()来遍历LinkedList
        LinkedList<Integer> temp2 = new LinkedList<>();
        temp2.addAll(linkedList);
        start = System.currentTimeMillis();
        while(temp2.size() != 0){
            temp2.removeFirst();
        }
        end = System.currentTimeMillis();
        System.out.println("removeFirst()或removeLast():" + (end - start) +" ms");
    }
}
/**Output
LinkedList: [0, 1, 2, 3]
getFirst(): 0
getLast(): 3
removeFirst(): 0
removeLast(): 3
After remove:[1, 2]
contains(1) is :true
size is : 2
-----------------------------------------
After set(1, 3):[1, 3]
get(1): 3
-----------------------------------------
indexOf(3): 1
lastIndexOf(3): 2
-----------------------------------------
peek(): 1
element(): 1
After poll():[3, 3]
After remove():[3]
After offer(4):[3, 4]
-----------------------------------------
After offerFirst(2):[2, 3, 4]
After offerLast(5):[2, 3, 4, 5]
peekFirst(): 2
peekLast(): 5
After pollFirst():[3, 4, 5]
After pollLast():[3, 4]
After push(2):[2, 3, 4]
After pop():[3, 4]
After removeFirstOccurrence(3):[4, 3]
After removeFirstOccurrence(3):[4]
-----------------------------------------
Iterator:17 ms
for:8419 ms
for2:12 ms
pollFirst()或pollLast():12 ms
removeFirst()或removeLast():10 ms
*/

2.顺序表

(1)ArrayList简介

ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。

ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。

ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList

(2)arraylist也有三种遍历方式,和LinkedList一样

(3)ArrayList用例详解

import java.util.*;

/*
 * @desc ArrayList常用API的测试程序
 */
public class ArrayListTest {

    public static void main(String[] args) {
        
        // 创建ArrayList
        ArrayList list = new ArrayList();

        // 将“”
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        // 将下面的元素添加到第1个位置
        list.add(0, "5");

        // 获取第1个元素
        System.out.println("the first element is: "+ list.get(0));
        // 删除“3”
        list.remove("3");
        // 获取ArrayList的大小
        System.out.println("Arraylist size=: "+ list.size());
        // 判断list中是否包含"3"
        System.out.println("ArrayList contains 3 is: "+ list.contains(3));
        // 设置第2个元素为10
        list.set(1, "10");

        // 通过Iterator遍历ArrayList
        for(Iterator iter = list.iterator(); iter.hasNext(); ) {
            System.out.println("next is: "+ iter.next());
        }

        // 将ArrayList转换为数组
        String[] arr = (String[])list.toArray(new String[0]);
        for (String str:arr)
            System.out.println("str: "+ str);

        // 清空ArrayList
        list.clear();
        // 判断ArrayList是否为空
        System.out.println("ArrayList is empty: "+ list.isEmpty());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值