package algorithm;
/**
* author : fzy
* date : 2019/11/12 8:26
* desc : 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
* 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
*/
public class demo6 {
public static void main(String[] args) {
int [] array = {6,7,8,9,3,4};
System.out.println(findMin1(array));
System.out.println(findMin2(array));
}
//方法一
public static int findMin1(int[] array){
int i = 0;
while (array[i]<array[i+1]){
i++;
}
return array[i+1];
}
//方法二
public static int findMin2(int[]array){
int low = 0;
int high = array.length - 1;
int middle = 0;
while (array[low]>array[high]){
//只有两个数时,最右侧为最小值
if(high - low == 1){
middle = high;
break;
}
middle = (low+high)/2;
if(array[middle]>=array[low]){
low = middle;
}else if(array[middle]<=array[high]){
high = middle;
}
}
return array[middle];
}
}
题目:输出斐波那契数列第n项:
/**
* author : fzy
* date : 2019/11/14 8:23
* 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
* 0 1 1 2 3 5 8 13.....
* n>2时,fn = fn-1 + fn-2
*/
public class demo7 {
public static void main(String[] args) {
int n = 7;
System.out.println(fibonacci(n));
}
public static int fibonacci(int n){
if(n==0){
return 0;
}else if(n==1){
return 1;
}else{
int zero = 0;
int one = 1;
int fN = 0;
for(int i=2;i<=n;i++){
fN = one + zero;
zero = one;
one = fN;
}
return fN;
}
}
}
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
package algorithm;
/**
* author : fzy
* date : 2019/11/15 8:29
* 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
*/
public class demo8 {
public static void main(String[] args) {
System.out.println(JumpFloor1(15));
System.out.println(JumpFloor2(15));
}
//第n阶等于n-1阶和n-2阶的和
public static int JumpFloor1(int n){
if(n<1)
return 0;
if(n==1)
return 1;
if(n==2)
return 2;
return JumpFloor1(n-1)+JumpFloor1(n-2);
}
//斐波那契数列解法
public static int JumpFloor2(int n){
if(n==1){
return 1;
}
if(n==2){
return 2;
}
int one = 1;
int two = 2;
int count = 0;
for(int i=3;i<=n;i++){
count = one + two;
one = two;
two = count;
}
return count;
}
}
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
package algorithm;
/**
* author : fzy
* date : 2019/11/16 8:27
* 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
* 求该青蛙跳上一个n级的台阶总共有多少种跳法。
*/
public class demo9 {
public static void main(String[] args) {
System.out.println(jumpFloor2(10));
System.out.println(jumpFloorII(10));
}
//发现规律,计算2的(n-1)次方
public static int jumpFloor2(int n) {
int fn = 1;
for(int i=1;i<n;i++){
fn = fn * 2;
}
return fn;
}
//每一阶等于前面一阶的方法数加一,采用动态规划
public static int jumpFloorIII(int n){
int first = 1;
int sum = 1;
while (n > 1){
sum += first;
first = sum;
n -- ;
}
return sum;
}
}
题目:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?(本质还是斐波那契数列,可用递归或动态规划解决,同上面
)
题目:反转链表,并且输出反转后的链表
package algorithm;
import bean.ListNode;
/**
* author : fzy
* date : 2019/11/20 8:33
* desc : 反转链表,并输出反转后的链表
*/
public class demo11 {
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode node1 = new ListNode(2);
ListNode node2 = new ListNode(3);
ListNode node3 = new ListNode(4);
ListNode end = new ListNode(5);
head.setNext(node1);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(end);
//System.out.println(reverseNode(head).getValue());
ListNode node = reverseNode(head);
while (node!=null){
System.out.println("node is:"+node.getValue());
node = node.getNext();
}
}
public static ListNode reverseNode(ListNode head){
ListNode reverseNode = null;//反转后的头结点
ListNode currentHead = head;
ListNode previoursNode = null;
while (currentHead!=null){
ListNode nextNode = currentHead.getNext();
if(nextNode==null){
reverseNode = currentHead;
}
currentHead.setNext(previoursNode);
previoursNode = currentHead;
currentHead = nextNode;
}
return reverseNode;
}
}
package bean;
/**
* author : fzy
* date : 2019/11/8 8:29
*/
public class ListNode {
private int value;
private ListNode next;
public ListNode(int value) {
this.value = value;
}
public ListNode(int value, ListNode next) {
this.value = value;
this.next = next;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。(合并链表)
package algorithm;
import bean.ListNode;
/**
* author : fzy
* date : 2019/11/21 8:53
* desc : 合并链表
*/
public class demo12 {
public static void main(String[] args) {
ListNode head1 = new ListNode(1);
ListNode node3 = new ListNode(2);
ListNode node5 = new ListNode(3);
ListNode node7 = new ListNode(7);
head1.setNext(node3);
node3.setNext(node5);
node5.setNext(node7);
ListNode head2 = new ListNode(4);
ListNode node4 = new ListNode(5);
ListNode node6 = new ListNode(6);
ListNode node8 = new ListNode(8);
head2.setNext(node4);
node4.setNext(node6);
node6.setNext(node8);
ListNode result = combineList(head1,head2);
while (result!=null){
System.out.println(result.getValue());
result = result.getNext();
}
}
//方法一:递归
public static ListNode combineList(ListNode head1,ListNode head2){
if(head1==null){
return head2;
}else if(head2==null){
return head1;
}
ListNode listAll = null;
if(head1.getValue()<head2.getValue()){
listAll = head1;
listAll.setNext(combineList(head1.getNext(),head2));
}else{
listAll = head2;
listAll.setNext(combineList(head1,head2.getNext()));
}
return listAll;
}
//方法二:非递归
public static ListNode mergeList(ListNode head1,ListNode head2){
ListNode result = null;
ListNode currentNode = null;
while (head1!=null&&head2!=null){
if(head1.getValue()<head2.getValue()){
if(result==null){
result = head1;
}else{
currentNode.setNext(head1);
}
currentNode = head1;
head1 = head1.getNext();
}else{
if(result==null){
result.setNext(head2);
}else{
currentNode.setNext(head2);
}
currentNode = head2;
head2 = head2.getNext();
}
}
if(head1==null&&head2!=null){
currentNode.setNext(head2);
}
if(head2==null&&head1!=null){
currentNode.setNext(head1);
}
return result;
}
}
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
package algorithm;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* author : fzy
* date : 2019/11/26 8:30
*/
public class demo13 {
public static void main(String[] args) {
List<Integer>list1 = new ArrayList<>();
list1.add(1);
list1.add(3);
list1.add(2);
list1.add(4);
list1.add(5);
List<Integer>list2 = new ArrayList<>();
list2.add(5);
list2.add(4);
list2.add(3);
list2.add(2);
list2.add(1);
System.out.println(isPopOrder(list1,list2));
Stack<Integer>stack1 = new Stack<>();
stack1.push(1);
stack1.push(2);
stack1.push(4);
stack1.push(3);
stack1.push(5);
Stack<Integer>stack2 = new Stack<>();
stack2.push(5);
stack2.push(3);
stack2.push(4);
stack2.push(2);
stack2.push(1);
System.out.println(isPopOrder2(stack1,stack2));
int[]array1 = {1,2,3,4,5};
int[]array2 = {5,4,3,2,1};
System.out.println(IsPopOrder(array1,array2));
}
public static boolean isPopOrder(List<Integer> list, List<Integer>pop){
Stack<Integer>push = new Stack<>();
for(int i=0;i<list.size();i++){
push.push(list.get(i));
}
int i = 0;
while (!push.empty()){
if(push.pop()!=pop.get(i)){
return false;
}else {
i++;
}
}
return true;
}
public static boolean isPopOrder2(Stack<Integer>stack1,Stack<Integer>stack2){
Stack<Integer>copy = new Stack<>();
while (!stack1.empty()){
copy.push(stack1.pop());
}
while (!copy.empty()){
if(copy.pop()!=stack2.pop()){
return false;
}
}
return true;
}
public static boolean IsPopOrder(int [] pushA,int [] popA) {
Stack<Integer> assistant = new Stack<Integer>();
int index = 0;//用于标识弹出序列位置
for(int i=0; i < pushA.length;i++)
{
assistant.push(pushA[i]);
//如果栈不为空,且栈顶元素等于弹出序列
while(!assistant.isEmpty() && assistant.peek() == popA[index])
{
assistant.pop();
index += 1;//弹出序列后移
}
}
return assistant.isEmpty();
}
}
题目:统计一个数字在排序数组中出现的次数。
package algorithm;
/**
* author : fzy
* date : 2019/11/27 8:47
* 统计一个数字在排序数组中出现的次数。
*/
public class demo14 {
public static void main(String[] args) {
int[]array = {1,2,3,4,4};
System.out.println(solution1(array,2));
}
public static int solution1(int[]array,int k){
int num = 0;
for(int i=0;i<array.length;i++){
if(array[i]==k){
num++;
}else{
if(num!=0){
break;
}
}
}
return num;
}
public static int GetNumberOfK(int [] array , int k) {
if (array == null || array.length == 0) return 0;
HashMap<Integer, Integer> map = new HashMap<>();
int result = 0;
for(int i=0;i<array.length;i++) {
int a = array[i];
if (map.containsKey(a)) {
map.put(a, map.get(a) + 1);
}else{
map.put(a, 1);
}
}
if (map.get(k) != null) {
result = map.get(k);
}
return result;
}
}
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
package algorithm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* author : fzy
* date : 2019/11/28 8:22
* desc : 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
*/
public class demo15 {
public static void main(String[] args) {
int[]array = {2,4,3,6,3,2,5,5};
int[]num1 = new int[1];
int[]num2 = new int[2];
FindNumsAppearOnce(array,num1,num2);
System.out.println(num1[0]);
System.out.println(num2[0]);
}
public static void FindNumsAppearOnce(int[]array,int [] num1,int[]num2){
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<array.length;i++){
if(map.containsKey(array[i])){
int value = map.get(array[i]);
map.put(array[i],value+1);
}else{
map.put(array[i],1);
}
}
int index = 0;
for(int i=0;i<array.length;i++){
if(map.get(array[i])==1){
if(index==0){
num1[0] = array[i];
index++;
}else{
num2[0] = array[i];
break;
}
}
}
}
public static void FindNumsAppearOnce2(int[]array,int [] num1,int[]num2){
List<Integer>listA = new ArrayList<>();
List<Integer>listB = new ArrayList<>();
for(int i=0;i<array.length;i++){
Integer value = array[i];
if(!listA.contains(value)&&!listB.contains(value)){
listA.add(value);
}else{
listA.remove(value);
listB.add(value);
}
}
num1[0]=listA.get(0);
num2[0]=listA.get(1);
}
}
题目:输入两个链表,找出它们的第一个公共结点。
package algorithm;
import bean.ListNode;
/**
* author : fzy
* date : 2019/11/29 8:34
* desc : 输入两个链表,找出它们的第一个公共结点。
* 首先要理解什么是公共节点,并不是两个节点的值相同就是公共节点。
* 而是在第一链表和第二链表中都存在一个节点,该节点往后的子链表在两个链表中是相同的。
*/
public class demo16 {
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
ListNode node6 = new ListNode(6);
ListNode head2 = new ListNode(10);
ListNode node7 = new ListNode(9);
head2.setNext(node7);
node7.setNext(head);
head.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
node5.setNext(node6);
System.out.println(getListNodeLength(head2));
}
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int length1 = getListNodeLength(pHead1);
int length2 = getListNodeLength(pHead2);
int diff = 0;
ListNode longNode;
ListNode shortNode;
if(length1>length2){
diff = length1 - length2;
longNode = pHead1;
shortNode = pHead2;
}else{
diff = length2 - length1;
longNode = pHead2;
shortNode = pHead1;
}
while (diff!=0){
longNode = longNode.getNext();
diff--;
}
while (longNode!=null&&shortNode!=null&&longNode!=shortNode){
longNode = longNode.getNext();
shortNode = shortNode.getNext();
}
return longNode;
}
public static int getListNodeLength(ListNode listNode){
if(listNode==null)
return 0;
int i=1;
while (listNode.getNext()!=null){
listNode = listNode.getNext();
i++;
}
return i;
}
}
题目:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
package algorithm;
import java.util.HashMap;
import java.util.Map;
/**
* author : fzy
* date : 2019/11/30 8:46
* desc : 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
*/
public class demo17 {
public static void main(String[] args) {
System.out.println(FirstNotRepeatingChar("qaCkq"));
}
//FirstNotRepeatingChar()根据分割后的数组个数不能适用于重复字母在最后一位的情况,如:qaCkq
public static int FirstNotRepeatingChar(String str) {
if (str == null || str.length() == 0) {
return -1;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
String[] arr = str.split(String.valueOf(c));
if (arr.length == 2) {
return i;
}
}
return -1;
}
public static int FirstNotRepeatingChar1(String str) {
if (str == null || str.length() == 0) {
return -1;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
String[] arr = str.split(String.valueOf(c));
if (arr.length == 2&&str.charAt(str.length()-1)!=c) {
return i;
}
}
return -1;
}
public static int FirstNotRepeatingChar2(String str) {
if (str == null || str.length() == 0) {
return -1;
}
Map<Character,Integer> map = new HashMap<Character,Integer>();
for(int i=0;i<str.length();i++){
if(map.containsKey(str.charAt(i))){
int val = map.get(str.charAt(i));
map.put(str.charAt(i),val+1);
}else{
map.put(str.charAt(i),1);
}
}
for(int i=0;i<str.length();i++){
if(map.get(str.charAt(i))==1){
return i;
}
}
return -1;
}
//在牛客网测试性能最优
public static int FirstNotRepeatingChar3(String str) {
if (str == null || str.length() == 0) {
return -1;
}
HashSet<Character> set = new HashSet<>();
for(int i=0;i<str.length();i++){
for(int j=i+1;j<str.length();j++){
if(str.charAt(i)==str.charAt(j)){
set.add(str.charAt(i));
break;
}else if(j==str.length()-1&&!set.contains(str.charAt(i))){
return i;
}
}
}
return -1;
}
}