题1:
204. 计数质数
统计所有小于非负整数 n
的质数的数量。
示例 1:
输入:n = 10 输出:4 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:
输入:n = 0 输出:0
示例 3:
输入:n = 1 输出:0
提示:
0 <= n <= 5 * 106
1 class Solution { 2 public int countPrimes(int n) { 3 if (n==0||n==1) return 0; 4 boolean[] flag=new boolean[n]; 5 Arrays.fill(flag,true); 6 //假设全是质数 7 for (int i=2;i*i<n;i++){ 8 if (flag[i]) { 9 for (int j=i*i;j<n;j+=i){ 10 flag[j]=false; 11 } 12 } 13 } 14 int ans=0; 15 for (boolean x:flag) { 16 if (x) ans++; 17 } 18 return ans-2; 19 } 20 }
思路: 埃氏筛。如果一个数x是质数,则2x,3x。。。 都是质数,可以提前过滤。此外合数y=a*b,a,b为质数,a<b则y已经被a过滤,当枚举到b时,另外一个因数小于b的情况已经全部被过滤,所以直接从b*b开始过滤。因次外循环到i*i<n即可。
题2:
172. 阶乘后的零
给定一个整数 n
,返回 n!
结果中尾随零的数量。
提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
示例 1:
输入:n = 3 输出:0 解释:3! = 6 ,不含尾随 0
示例 2:
输入:n = 5 输出:1 解释:5! = 120 ,有一个尾随 0
示例 3:
输入:n = 0 输出:0
提示:
0 <= n <= 104
进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?
1 class Solution { 2 public int trailingZeroes(int n) { 3 long mul=5; 4 int ans=0; 5 while (mul<=n) { 6 ans+=n/mul; 7 mul*=5; 8 } 9 return ans; 10 } 11 }
思路:0的出现是由于2*5的出现,所以统计2与5因子中较小的那个即可。2的因子数必定超过5,所以只需要统计5的因子数,5~25之间是n/5,25~125需要加上25倍数个5,n/125,依次类推。
题3:
382. 链表随机节点
给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。
实现 Solution
类:
-
Solution(ListNode head)
使用整数数组初始化对象。 -
int getRandom()
从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相等。
示例:
输入 ["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"] [[[1, 2, 3]], [], [], [], [], []] 输出 [null, 1, 3, 2, 2, 3] 解释 Solution solution = new Solution([1, 2, 3]); solution.getRandom(); // 返回 1 solution.getRandom(); // 返回 3 solution.getRandom(); // 返回 2 solution.getRandom(); // 返回 2 solution.getRandom(); // 返回 3 // getRandom() 方法应随机返回 1、2、3中的一个,每个元素被返回的概率相等。
提示:
- 链表中的节点数在范围
[1, 104]
内 -104 <= Node.val <= 104
- 至多调用
getRandom
方法104
次
进阶:
- 如果链表非常大且长度未知,该怎么处理?
- 你能否在不使用额外空间的情况下解决此问题?
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode() {} 7 * ListNode(int val) { this.val = val; } 8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 9 * } 10 */ 11 class Solution { 12 List<ListNode> list; 13 public Solution(ListNode head) { 14 list=new ArrayList<>(); 15 ListNode root=head; 16 while (root!=null) { 17 list.add(root); 18 root=root.next; 19 } 20 } 21 22 public int getRandom() { 23 Random rand=new Random(); 24 return list.get(rand.nextInt(list.size())).val; 25 } 26 } 27 28 /** 29 * Your Solution object will be instantiated and called as such: 30 * Solution obj = new Solution(head); 31 * int param_1 = obj.getRandom(); 32 */
思路:列表+随机索引实现。
题4:
398. 随机数索引
给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。
注意:
数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。
示例:
int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) 应该返回索引 2,3 或者 4。每个索引的返回概率应该相等。 solution.pick(3); // pick(1) 应该返回 0。因为只有nums[0]等于1。 solution.pick(1);
1 class Solution { 2 Map<Integer,List<Integer>> map; 3 public Solution(int[] nums) { 4 map=new HashMap<>(); 5 for (int i=0;i<nums.length;i++){ 6 if (!map.containsKey(nums[i])){ 7 map.put(nums[i],new ArrayList<>()); 8 } 9 map.get(nums[i]).add(i); 10 } 11 } 12 13 public int pick(int target) { 14 Random rand=new Random(); 15 int index=rand.nextInt(map.get(target).size()); 16 return map.get(target).get(index); 17 } 18 } 19 20 /** 21 * Your Solution object will be instantiated and called as such: 22 * Solution obj = new Solution(nums); 23 * int param_1 = obj.pick(target); 24 */
思路:哈希表加列表和随机数索引实现。