LL今天心情特别好,由于他去买了一副扑克牌,发现里面竟然有2个大王,2个小王(一副牌本来是54张^_^)...他随机从中抽出了5张牌,想测测本身的手气,看看能不能抽到顺子,若是抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王能够当作任何数字,而且A看做1,J为11,Q为12,K为13。上面的5张牌就能够变成“1,2,3,4,5”(大小王分别看做2和4),“So Lucky!”。LL决定去买体育彩票啦。 如今,要求你使用这幅牌模拟上面的过程,而后告诉咱们LL的运气如何。为了方便起见,你能够认为大小王是0。java
import java.util.Arrays; public class Solution { public boolean isContinuous(int [] numbers) { if(numbers.length < 5) return false; Arrays.sort(numbers); int zerosNum = 0; int needZeros = 0; for(int i = 0 ;i < 5;i++){ if(numbers[i] == 0){ zerosNum++; }else if(i+1<5){ //如存在两数字相同,则必定不是顺子 if(numbers[i+1] == numbers[i]) return false; needZeros += numbers[i+1] - numbers[i] -1; } } //此时大王个数超过四个,不符合题目要求 if(zerosNum > 4) return false; if(zerosNum >= needZeros) return true; else return false; } }
n我的(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人 继续从0开始报数。求胜利者的编号。(约瑟夫环问题)
解法一:使用数组模拟环node
public class Solution { public int LastRemaining_Solution(int n, int m) { if(n<0||m<1) return -1; int[] array = new int[n]; int count=n,step=0,idx=-1; while(count>0){ idx++; if(idx == n) idx=0; if(array[idx] == -1) continue;//若是是被标记过的则跳过 step++; if(step == m){ array[idx] = -1; count--; step=0; } } return idx; } }
解法二:使用ArrayList模拟环
正则表达式
import java.util.ArrayList; public class Solution { public int LastRemaining_Solution(int n, int m){ if(n<0||m<1) return -1; ArrayList<Integer> list = new ArrayList<>(); for(int i = 0;i<n;i++) list.add(i); int idx = (m-1)%n; while(list.size()>1){ list.remove(idx); idx = (idx+m-1)%list.size(); } return list.get(0); } }
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。数组
解题思路:(短路求值)app
public class Solution { public int Sum_Solution(int n) { int sum = n; boolean isEnd = (sum != 0)&&((sum += Sum_Solution(n-1))>0); return sum; } }
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。函数
解析:按位运算oop
public class Solution { public int Add(int num1,int num2) { int n1,n2; n1 = num1 & num2; n1 = n1<<1; n2 = num1 ^ num2; if((n1 & n2) != 0) return Add(n1,n2); return n1 | n2; } }
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
this
public class Solution { public int StrToInt(String str) { if(str.length() < 1) return 0; char[] nums = str.toCharArray(); int result = 0; int flag = 1; for(int i = 0 ; i<nums.length ; i++){ if(nums[i]-'0'>9 || nums[i]-'0'<0){ if( i==0 && (nums[i] == '+' || nums[i] == '-')) flag = nums[i] == '+' ? 1 : -1; else return 0; }else{ result*=10; result+=(nums[i]-'0'); } } return result*flag; } }
不适用str.toCharArray()方法google
public class Solution { public int StrToInt(String str) { if(str.length() < 1) return 0; int result = 0; int flag = 1; for(int i = 0 ; i<str.length(); i++){ if(str.charAt(i)-'0'>9 || str.charAt(i)-'0'<0){ if( i==0 && (str.charAt(i) == '+' || str.charAt(i) == '-')) flag = str.charAt(i) == '+' ? 1 : -1; else return 0; }else{ result*=10; result+=(str.charAt(i)-'0'); } } return result*flag; } }
在一个长度为n的数组里的全部数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每一个数字重复几回。请找出数组中任意一个重复的数字。 例如,若是输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。指针
public class Solution { // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation; // Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++ // 这里要特别注意~返回任意重复的一个,赋值duplication[0] // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false public boolean duplicate(int numbers[],int length,int [] duplication) { if(length<0) return false; boolean[] result = new boolean[length]; for(int i = 0;i<length;i++){ if(numbers[i]>length-1||numbers[i]<0) return false; if(result[numbers[i]]){ duplication[0] = numbers[i]; return true; } result[numbers[i]] = true; } return false; } }
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...A[i-1]A[i+1]...A[n-1]。不能使用除法。
import java.util.ArrayList; public class Solution { public int[] multiply(int[] A) { int[] B = new int[A.length]; if(A.length == 0) return B; B[0] = 1; for(int i = 1;i<A.length;i++){ B[i] = B[i-1] * A[i-1]; } int temp = 1; for(int i = A.length-1;i>=0;i--){ B[i] *= temp; temp *= A[i]; } return B; } }
请实现一个函数用来匹配包括'.'和''的正则表达式。模式中的字符'.'表示任意一个字符,而''表示它前面的字符能够出现任意次(包含0次)。 在本题中,匹配是指字符串的全部字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,可是与"aa.a"和"ab*a"均不匹配
解题思路
1.当patternIndex后一位为‘’时:
此时若strIndex == str.length时,直接将patternIndex+2,跳过两个;
若是strIndex!=str.length时,分为如下三种状况:
1.strIndex,patternIndex+2;(str != pattern时)
2.strIndex+1,patternIndex+2;(str = pattern 时 或者 此时pattern == ‘.’)
3.strIndex+1,patternIndex;(str == pattern 并且 str+1 也 == pattern)
2.当patternIndex后一位不为‘’
此时若是strIndex = str.length return false;
若是 str = pattern 则 str+1,pattern+1
反之 return false;
public class Solution { public boolean match(char[] str, char[] pattern) { //1.边缘检测 if(str==null||pattern==null) return false; int strIndex=0,patternIndex=0; return matchCore(str,pattern,strIndex,patternIndex); } public boolean matchCore(char[] str,char[] pattern,int strIndex,int patternIndex){ if(strIndex == str.length && patternIndex == pattern.length) return true; if(strIndex != str.length && patternIndex == pattern.length) return false; //当模式中第二个字符是‘*’ if(patternIndex+1 < pattern.length && pattern[patternIndex +1] == '*'){ //必定注意这里strIndex有多是str.length 须要把str[strIndex]放在后面,以避免溢出 if(strIndex != str.length && (pattern[patternIndex] == '.' || str[strIndex] == pattern[patternIndex])){ return matchCore(str,pattern,strIndex+1,patternIndex) || matchCore(str,pattern,strIndex+1,patternIndex+2) || matchCore(str,pattern,strIndex,patternIndex+2); }else{ return matchCore(str,pattern,strIndex,patternIndex+2); } }else{//模式中第二个字符不是’*‘ if(strIndex != str.length && (str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.')) return matchCore(str,pattern,strIndex+1,patternIndex+1); else return false; } } }
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 可是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
题目分析:数值能够表示为"A+'.'+B+'E/e'+C"
public class Solution { //声明一个全局变量,记录小数点前是否有数字 boolean hasInt = false; public boolean isNumeric(char[] str) { if(str == null || str.length == 0) return false; return scanA(str,0); } //第一部分:为带符号整数,后续字符串可包括'./e/E' public boolean scanA(char[] str,int index){ //1.若是有符号则跳过。 if(str[index] == '-' || str[index] == '+') index++; while(index < str.length && str[index]-'0' <= 9 && str[index]-'0' >= 0){ hasInt = true; index++; } if(index == str.length) return hasInt; if(str[index] == '.') return scanB(str,index+1); else if(str[index] == 'e'||str[index]=='E') return scanC(str,index+1); else return false; } //第二部分:为不带符号整数,后续字符可带'e/E' public boolean scanB(char[] str,int index){ boolean hasNum = false; //用于判断是不是“12.”这种数字 if(index == str.length) return hasInt || hasNum; while(index < str.length && str[index]-'0' <= 9 && str[index]-'0' >= 0){ index++; hasNum = true; } if(index == str.length) return hasInt || hasNum; if(str[index] == 'e' || str[index] == 'E') return (hasInt || hasNum) && scanC(str,index+1); else return false; } //第三部分:为带符号整数 public boolean scanC(char[] str,int index){ //用于判断是否为“12e”这样的数字,这种是不正确的,第三部分不能为空 if(index == str.length) return false; boolean hasNum = false; //若是有符号,则跳过 if(str[index]=='+'||str[index]=='-') index++; while(index < str.length && str[index]-'0' <= 9 && str[index]-'0' >= 0){ hasNum=true; index++; } if(index == str.length) return hasNum; else return false; } }
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
若是当前字符流没有存在出现一次的字符,返回#字符。
import java.util.ArrayList; import java.util.HashSet; public class Solution { ArrayList<Character> list = new ArrayList<>(); HashSet<Character> set = new HashSet<>(); //Insert one char from stringstream public void Insert(char ch) { if(!set.contains(ch)) if(list.contains(ch)){ //注意这里之因此将char转换为Character对象,是由于,若是直接带入char //函数会将char转变成ASCII码int值做为索引,会致使溢出。 list.remove((Character)ch); set.add(ch); }else{ list.add(ch); } } //return the first appearence once char in current stringstream public char FirstAppearingOnce() { if(list.size() > 0) return list.get(0); else return '#'; } }
一个链表中包含环,请找出该链表的环的入口结点。
方法一:使用辅助Set集合
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ import java.util.HashSet; public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if(pHead == null) return null; HashSet<ListNode> set = new HashSet<>(); while(!set.contains(pHead)){ if(pHead.next == null) return null; set.add(pHead); pHead = pHead.next; } return pHead; } }
方法二:单纯指针操做
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if(pHead == null) return null; ListNode p1=pHead,p2=pHead.next; //第一步:若是有环,则算出环的长度; while(p1 != p2 && p2 != null){ p1 = p1.next; p2 = p2.next; if(p2 == null) return null; p2 = p2.next; } if(p2 == null) return null; int count = 1; while(p1.next != p2){ p1 = p1.next; count++; } //第二步:找到环的入口 p1 = pHead; p2 = pHead; while(count-- > 0) p2 = p2.next; while(p1!=p2){ p1 = p1.next; p2 = p2.next; } return p1; } }
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public ListNode deleteDuplication(ListNode pHead) { if(pHead == null || pHead.next == null) return pHead; if(pHead.val == pHead.next.val){ while(pHead.next != null && pHead.val == pHead.next.val) pHead = pHead.next; return deleteDuplication(pHead.next); } pHead.next = deleteDuplication(pHead.next); return pHead; } }
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点而且返回。注意,树中的结点不只包含左右子结点,同时包含指向父结点的指针。
/* public class TreeLinkNode { int val; TreeLinkNode left = null; TreeLinkNode right = null; TreeLinkNode next = null; TreeLinkNode(int val) { this.val = val; } } */ public class Solution { public TreeLinkNode GetNext(TreeLinkNode pNode) { if(pNode == null) return null; if(pNode.right != null){ TreeLinkNode node = pNode.right; while(node.left != null) node = node.left; return node; } while(pNode.next != null){ if(pNode.next.right != pNode) return pNode.next; pNode = pNode.next; } return null; } }