链表反转-迭代-递归
有序链表1->2->3->4->5
需要其输出反转==>>5->4->3->2->1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| public class ReverseList { static class ListNode { int val; ListNode next;
public ListNode(int val, ListNode next) { this.val = val; this.next = next; } }
public static ListNode reversalList(ListNode head){ ListNode next,pre=null; ListNode current=head; while(current!=null){ next=current.next; current.next=pre; pre=current; current=next; }
return pre;
}
public static ListNode reversalList2(ListNode head){ if(head==null||head.next==null){ return head; } ListNode new_head = reversalList2(head.next); head.next.next=head; head.next=null;
return new_head; }
public static void printNode(ListNode node){ System.out.print(node.val); while (node.next!=null){ node=node.next; System.out.print("->"+node.val); } System.out.println(); }
public static void main(String args[]) {
ListNode node5 = new ListNode(5, null); ListNode node4 = new ListNode(4, node5); ListNode node3 = new ListNode(3, node4); ListNode node2 = new ListNode(2, node3); ListNode node1 = new ListNode(1, node2);
System.out.println("翻转前:"); printNode(node1);
ListNode node = reversalList2(node1);
System.out.println("翻转后:"); printNode(node);
} }
|
统计n以内的素数个数-暴力-埃氏筛选
素数:只能被1和自身整除的自然数 0,1 除外
暴力算法和埃氏筛选:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| package com.hnit.day02;
import java.util.Scanner;
public class SuShu { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); System.out.println("输入一个整数n: "); int n = scanner.nextInt();
int result1 = bf(n); int result2 = eratosthenes(n); System.out.println("暴力算法: " + n + "以内的素数个数为:" + result1 + "个"); System.out.println("埃氏筛法: " + n + "以内的素数个数为:" + result2 + "个"); }
public static int bf(int n) { int count = 0; for (int i = 2; i <= n; i++) { count += isPrime(i) ? 1 : 0; } return count; }
private static boolean isPrime(int x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) { return false; } } return true; }
public static int eratosthenes(int n) { boolean[] isPrime = new boolean[n+1]; int count = 0; for (int i = 2; i <= n; i++) { if (!isPrime[i]) { count++;
for (int j = i * i; j < n; j += i) { isPrime[j] = true; } } } return count; } }
|
删除排序数组中的重复项-双指针
一个有序数组nums,原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。
不能使用额外的数组空间,必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。
例如: 输入:[0,1,2,2,3,3,4]
输出:5
双指针算法:
思路:数组完成排序后,我们可以放置两个指针i和j,i为慢指针,j为快指针。
只要当nums[i]==nums[j],我们就增加j来跳过重复项
当nums[i]!=nums[j]时,说明重复项已经跳完,将nums[j]的值赋予nums[i+1],然后i++。
接着重复相同的过程,直到j到达数组的末尾为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package com.hnit.day03;
public class SortedArrayDuplicates {
public static void main(String[] args) { int [] nums=new int[]{0,1,2,2,3,3,4}; int result=removeDuplicates(nums); System.out.println("数组新长度为:"+result); }
public static int removeDuplicates(int[] nums) { if(nums.length==0){ return 0; } int i=0; for(int j=1;j<nums.length;j++){ if(nums[j]!=nums[i]) { i++; nums[i] = nums[j]; } } return i+1; } }
|
寻找数组的中心下标
给定一个整数数组nums,请编写一个能够返回数组“中心下标”的方法,
中心下标是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心下标,返回-1。如果数组有多个中心下标,应该返回靠近左边的那一个。
注意:中心下标可能出现在数组的两端。
思路:先统计出整个数组的总和,然后从第一个元素开始叠加。总和递减当前元素,叠加递增当前元素,直到两个值相等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.hnit.day04;
import java.util.Arrays;
public class ArrayCenterIndex { public static void main(String[] args) { System.out.println(pivotIndex2(new int[]{1, 7, 3, 6, 5, 6})); }
public static int pivotIndex(int[] nums) { int sum = Arrays.stream(nums).sum(); int total = 0; for(int i=0;i<nums.length;i++){ total+=nums[i]; if(total==sum){ return i; } sum = sum -nums[i]; } return -1; }
public static int pivotIndex2(int[] nums) { int sum = Arrays.stream(nums).sum(); int total = 0; for(int i=0;i<nums.length;i++){ if(total*2+nums[i]==sum){ return i; } total+=nums[i]; } return -1; } }
|
X的平方根-二分查找-牛顿迭代
在不使用sqrt(x)函数的情况下,得到x的平方根整数部分
解法一:二分查找
x的平方根肯定在0,X之间,使用二分查找定位该数字,该数字的平方一定是最接近x的,m平方值如果大于x,则往左边找,小于等于则往右边找
解法二:牛顿迭代
假设平方根是i,则i和x/i必然都是x的因子,而x/i必然等于i,推到出i+x/i=2*i,得出i=(i+x/i)/2
由此得出解法,i可以任取一个值,只要上述公式成立,i必然就是x的平方根,如果不成立,(i+x/i)/2得出的值进行递归,直至得出正确解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package day05;
public class SqrtX { public static void main(String[] args) { System.out.println(binarySearch(10)); System.out.println(newton(10)); }
public static int binarySearch(int x) { int l = 0, r = x, index = -1; int mid; while (l < r) { mid = l + (r - 1) / 2; if (mid * mid <= x) { index = mid; l = mid + 1; } else { r = mid - 1; } } return index; }
public static int newton(int x) { if(x==0) return 0; return (int) sqrt(x,x); }
public static double sqrt(double i,int x) { double res = (i+x/i)/2; if(res==i){ return i; }else{ return sqrt(res,x); } } }
|