26.删除数组中重复元素
自己写的是遍历一个数,找到其重复的个数,设置一个指针记录总重复数,也就找到了最后要访问的节点,有重复的则将后面的元素往前挪 |
设置快慢指针,慢指针不同才走,快指针走完全程时,慢指针刚好走到剩余元素完。 |
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null||nums.length == 0){
return 0;
}
if (nums.length == 1){
return 1;
}
int count = 0;
for (int x = 0;x<=nums.length-2-count;x++){
int y = x;
int temp_count = 0;
while (y <= nums.length-2-count && nums[y] == nums[y+1] ){
temp_count++;
y++;
}
if (temp_count != 0){
//前移
for (int z = x+temp_count+1;z<=nums.length-1;z++){
nums[z-temp_count] = nums[z];
}
count += temp_count;
}
}
return nums.length-count;
}
}
面试题122:买卖股票的最佳时间2
动态规划,从尾到头求在第n天买的最大价值是多少 |
题目意思可以当天卖了之后买,故把连续的差值相加即可 |
public static int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1){
return 0;
}
int days = prices.length;
int[] price_day = new int[days];
price_day[days-1] = 0;
for (int x = days-2;x>=0;x--){
int max = 0;
for (int y = x+1;y<=days-1;y++){
if (prices[y] > prices[x]){
int temp = prices[y] - prices[x];
if (y<= days-2){
temp += price_day[y+1];
}
if (temp > max){
max = temp;
}
}
}
//如果最大值比当天不买还小,取当天不买
if (maxmaxprice){
maxprice = x;
}
}
return maxprice;
}
面试题136:只出现一次的数字(剑指offer)
遍历异或 |
用hash表存下一个数组的元素,再进行比对 |
将两个数组排序,再进行比较 |
public int[] intersect(int[] nums1, int[] nums2) {
int[] reback = {};
if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0){
return reback;
}
List temp = new ArrayList<>();
Arrays.sort(nums1);
Arrays.sort(nums2);
int start = 0;
for (int x : nums2){
for (int y = start;y<=nums1.length-1;y++){
if (nums1[y] == x){
temp.add(x);
start = y+1;
break;
}
}
}
if (temp.size() == 0){
return reback;
}
reback = new int[temp.size()];
for (int x = 0;x<=reback.length-1;x++){
reback[x] = temp.get(x);
}
return reback;
}
面试题66:加一
从尾到头计算,考虑进位,可以直接把加一思考为一开始carry=1; |
public static int[] plusOne(int[] digits) {
if ( digits == null || digits.length == 0){
return digits;
}
int carry = 0;
digits[digits.length-1] = digits[digits.length-1]+1;
if (digits[digits.length-1]>=10){
digits[digits.length-1] = digits[digits.length-1]-10;
carry = 1;
}
for (int x = digits.length-2;x>=0;x--){
digits[x] = digits[x]+carry;
if (digits[x] >= 10){
digits[x] = digits[x]-10;
carry = 1;
}else {
carry = 0;
}
}
if (carry == 1){
int[] reback = new int[digits.length+1];
for (int x = 1;x<=reback.length-1;x++){
reback[x] = digits[x-1];
}
reback[0] = 1;
return reback;
}
return digits;
}
面试题283:移动0
冒泡的思想可解 |
用快慢指针,快指针找到非0位置后与前一个指针进行交换。 |
public static void moveZeroes(int[] nums) {
if (nums == null||nums.length <= 1){
return;
}
int count = 0;
for (int x = 0;x<=nums.length-2-count;x++){
if (nums[x] == 0){
count++;
for (int y = x;y<=nums.length-2;y++){
exchange(nums,y,y+1);
}
if (nums[x] == 0){
x--;
}
}
}
}
public static void exchange(int[] nums,int index1,int index2){
nums[index1] = nums[index1]^nums[index2];
nums[index2]= nums[index1]^nums[index2];
nums[index1] = nums[index1]^nums[index2];
}
面试题1:两数之和
若不要求返回下标,可以采用剑指offer上,对数组先排序再从头尾开始扫描的办法。 |
扫描数组,若hashmap有另一半则返回,若无,则将当前数添加进hashmap |
public int[] twoSum(int[] nums, int target) {
int[] reback = {};
if (nums == null || nums.length < 2){
return reback;
}
for (int x = 0;x<=nums.length-2;x++){
for (int y = x+1;y<=nums.length-1;y++){
if ((nums[x] + nums[y]) == target){
reback = new int[2];
reback[0] = x;
reback[1] = y;
return reback;
}
}
}
return reback;
}
面试题36:有效的数独
设置三个hashmap,在一次遍历中,通过数字转化到对应需要检查的位置,来完成一次遍历检查完 |
public static boolean isValidSudoku(char[][] board) {
if (board == null || board.length != 9 || board[0].length != 9){
return false;
}
HashMap hashMap_row = new HashMap<>();
HashMap hashMap_col = new HashMap<>();
HashMap hashMap_small = new HashMap<>();
for (int x = 0;x<=8;x++){
hashMap_row.clear();
hashMap_col.clear();
hashMap_small.clear();
for (int y = 0;y<=8;y++){
if (board[x][y] != '.'){
if (hashMap_row.containsKey(board[x][y])){
return false;
}else {
hashMap_row.put(board[x][y],true);
}
}
if (board[y][x] != '.'){
if (hashMap_col.containsKey(board[y][x])){
return false;
}else {
hashMap_col.put(board[y][x],true);
}
}
if (board[x/3*3+y/3][x%3*3+y%3] != '.'){
if (hashMap_small.containsKey(board[x/3*3+y/3][x%3*3+y%3])){
return false;
}else {
hashMap_small.put(board[x/3*3+y/3][x%3*3+y%3],true);
}
}
}
}
return true;
}
面试题48:旋转图像
先沿对角线交换一次元素,再按行的中轴旋转一次,得到旋转后的图像。 |
public static void rotate(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0 || matrix.length != matrix[0].length){
return;
}
int row = matrix.length;
//沿对角线交换
for (int x = 0;x<=row-2;x++){
for (int y = row-x-2;y>=0;y--){
swamp(matrix,x,y,row-1-y,row-1-x);
}
}
//沿中轴交换
int middle = (row-1)/2;
for (int x = 0;x<=middle;x++){
for (int y = 0;y<=row-1;y++){
swamp(matrix,x,y,row-1-x,y);
}
}
}
public static void swamp(int[][] matrix,int x1,int y1,int x2,int y2){
int temp = matrix[x1][y1];
matrix[x1][y1] = matrix[x2][y2];
matrix[x2][y2] = temp;
}
面试题344:反转字符串
遍历数组,交换元素的位置。 |
public static String reverseString(String s) {
if (s == null||s.length() <= 1){
return s;
}
int needreverse = (s.length()-1)/2;
char[] S_char = s.toCharArray();
for (int x = 0;x<=needreverse;x++){
swap(S_char,x,S_char.length-1-x);
}
return String.valueOf(S_char);
}
public static void swap(char[] S_char ,int index1,int index2){
char temp = S_char[index1];
S_char[index1] = S_char[index2];
S_char[index2] = temp;
}
面试题7:颠倒整数
将整数表示为字符串,在字符串中进行操作,并与最大值按位进行比较 |
可以不用翻转的思想,直接用整数进行预算,(除10,取余,保存)。先将结果用long保存,再进行比较,再输出 |
char[] num = String.valueOf(x).toCharArray();
//判断首位正负
String compare = (int)Math.pow(2,31)+"";
StringBuilder stringBuilder = new StringBuilder();
String st = "";
String st_sub = "";
if (num[0] == '-'){
st = swap(num,1,num.length-1);
st_sub = st.substring(1);
}else {
st = swap(num,0,num.length-1);
st_sub = st;
}
//低于10位不存在越界
if (st_sub.length() == 10){
for (int i = 0;i<10;i++){
if (i == 9 && st_sub.charAt(i) >compare.charAt(i)-1 || st_sub.charAt(i)>compare.charAt(i)){
return 0;
}else if (st_sub.charAt(i) < compare.charAt(i)){
break;
}
}
}
if (st == "0"){
return 0;
}else {
stringBuilder.append(st);
}
return Integer.parseInt(stringBuilder.toString());
面试题387:字符串中第一个唯一字符
hashmap辅助存储,遍历字符数组,再在hashmap中返回 |
字符只在a-z之间,则每次firstindex , lastindex某个字符,若相等则说明只出现一次 |
public static int firstUniqChar(String s) {
if (s == null || s.length() == 0){
return -1;
}
HashMap hashMap = new HashMap<>();
char[] temp = s.toCharArray();
for (int x = 0;x<=temp.length-1;x++){
if (hashMap.containsKey(temp[x])){
hashMap.replace(temp[x],-1);
}else {
hashMap.put(temp[x],x);
}
}
int firstindex = temp.length;
for (int x:hashMap.values()){
if (x
面试题242:验证变位词
用hashmap辅助存储 |
public static boolean isAnagram(String s, String t) {
if (s == null || t == null || s.length()!=t.length()){
return false;
}
HashMap hashMap = new HashMap<>();
for (char x:s.toCharArray()){
if (hashMap.containsKey(x)){
hashMap.replace(x,hashMap.get(x)+1);
}else {
hashMap.put(x,1);
}
}
for (char x:t.toCharArray()){
if (hashMap.containsKey(x)){
hashMap.replace(x,hashMap.get(x)-1);
}else {
return false;
}
}
for (int x:hashMap.values()){
if (x!=0){
return false;
}
}
return true;
}
面试题125:验证回文串
用队列辅助比较 |
设置两个指针一头一尾进行比较 |
public static boolean isPalindrome(String s) {
if (s == null){
return false;
}
if (s.length() <= 1){
return true;
}
ArrayDeque deque = new ArrayDeque() {};
char[] temp = s.toLowerCase().toCharArray();
for (char x:temp){
if ( ( (x<='z' && x>='a') || (x <='9'&& x>='0') )){
deque.addLast(x);
}
}
for (int x = temp.length-1;x>=0;x--){
if (( (temp[x]<='z' && temp[x]>='a') || (temp[x] <='9'&& temp[x]>='0') )){
char compare = deque.pollFirst();
if (compare != temp[x]){
return false;
}
}
}
return true;
}
面试题8:字符串转数组
每次检验sum是否会超过边界 |
public static int myAtoi(String str) {
if (str == null || str.length() == 0){
return 0;
}
char[] temp = str.toCharArray();
int startswords = 0;
for (int x = 0;x<=temp.length-2;x++){
if (temp[x] == ' '){
startswords++;
if (temp[x+1] != ' '){
break;
}
}else {
break;
}
}
if (startswords == temp.length-1 && startswords != 0){
return 0;
}
int num = 0;
if (temp[startswords] == '+' || temp[startswords] == '-'){
for (int x = startswords+1;x<=temp.length-1;x++){
if (temp[x]>'9' || temp[x] <'0'){
break;
}
if (num >Integer.MAX_VALUE/10 || (num == Integer.MAX_VALUE/10 && (temp[x]-'0') > 7)){
return temp[startswords] == '+'?Integer.MAX_VALUE:Integer.MIN_VALUE;
}
num = num*10+temp[x]-'0';
}
return temp[startswords] == '+'?num:-num;
}else if (temp[startswords] <= '9' && temp[startswords] >='0'){
for (int x = startswords;x<=temp.length-1;x++){
if (temp[x]>'9' || temp[x] <'0'){
break;
}
if (num >Integer.MAX_VALUE/10 || (num == Integer.MAX_VALUE/10 && (temp[x]-'0') >7)){
return Integer.MAX_VALUE;
}
num = num*10+temp[x]-'0';
}
return num;
}else {
return 0;
}
}
面试题28:实现strStr()
就是比较母串和子串,遍历到母串-子串长度即可 |
public static int strStr(String haystack, String needle) {
if (haystack == null || needle == null || needle.length() == 0){
return 0;
}
if (haystack.length() < needle.length()){
return -1;
}
char[] hay = haystack.toCharArray();
char[] need = needle.toCharArray();
for (int x = 0;x<=haystack.length()-1;x++){
if (hay[x] == need[0]){
if (x+need.length-1<=haystack.length()-1){
int y = 1;
for (;y<=need.length-1;y++){
if (hay[x+y] != need[y]){
break;
}
}
if (y == need.length){
return x;
}
}else {
return -1;
}
}
}
return -1;
}
面试题38:报数
按次数用n-1构造n即可,不可能出现超过3的数 |
public static String countAndSay(int n) {
if (n<=0){
return "";
}
StringBuilder stringBuilder = new StringBuilder();
if (n == 1){
stringBuilder.append("1");
return stringBuilder.toString();
}
stringBuilder.append("1");
while (n > 1){
char[] temp = stringBuilder.toString().toCharArray();
stringBuilder.delete(0,stringBuilder.length());
int count = 1;
if (temp.length == 1){
stringBuilder.append(1);
stringBuilder.append(temp[0]);
}
for (int x = 0;x<=temp.length-2;x++){
if (temp[x] == temp[x+1]){
count++;
if (x == temp.length-2){
stringBuilder.append(count);
stringBuilder.append(temp[x]);
count = 1;
}
}else {
stringBuilder.append(count);
stringBuilder.append(temp[x]);
count = 1;
}
}
if (temp.length>=2 && temp[temp.length-1] != temp[temp.length-2]){
stringBuilder.append(1);
stringBuilder.append(temp[temp.length-1]);
}
n = n-1;
}
return stringBuilder.toString();
}
面试题14:最长公共子串
遍历数组,两两求出公共子串,不断更新 |
选取第一个字符串中的字符,每个字符去其余字符串中比较是否有 |
public static String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0){
return "";
}
if (strs.length == 1){
return strs[0];
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(strs[0]);
for (int x = 1;x<=strs.length-1;x++){
if (stringBuilder.length() == 0){
return "";
}
String temp = compare(stringBuilder.toString(),strs[x]);
if (temp.length() < stringBuilder.length()){
stringBuilder.delete(0,stringBuilder.length());
stringBuilder.append(temp);
}
}
return stringBuilder.toString();
}
public static String compare(String st1,String st2){
int lenth = st1.length() >= st2.length() ? st2.length():st1.length();
StringBuilder stringBuilder = new StringBuilder();
char[] st_char = st1.toCharArray();
char[] st2_char = st2.toCharArray();
for (int x = 0;x<=lenth-1;x++){
if (st_char[x] == st2_char[x]){
stringBuilder.append(st_char[x]);
}else {
break;
}
}
return stringBuilder.toString();
}
面试题237:删除链表中的节点
用下一节点的值覆盖此节点,并指向下一节点的下一节点。 |
public static void deleteNode(ListNode node) {
if (node == null || node.next == null){
return;
}
node.val = node.next.val;
node.next = node.next.next;
}
面试题19:删除链表的倒数N个节点
用栈来进行辅助 |
用两个指针,一个指针先走N步 |
public static ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null){
return null;
}
ListNode temp = head;
Stack st = new Stack<>();
while (temp!=null){
st.push(temp);
temp = temp.next;
}
ListNode reback = null;
for (int x = 1;x<=n;x++){
reback = st.pop();
}
if (st.size() == 0){
return reback.next;
}else {
ListNode father = st.pop();
father.next = reback.next;
return head;
}
}
面试题206:翻转单链表
可以从头到尾遍历,每遍历一个就处理一个;可以设置新的头结点,将原头结点后的接到后面,直到原头结点为尾节点; 递归找到head == null || head.next == null,返回节点,每层保存当前节点; |
ublic static ListNode reverseList(ListNode head) {
if (head == null){
return null;
}
if (head.next == null){
return head;
}
ListNode temp = null;
while (head!= null){
ListNode nexttemp = head.next;
ListNode now = head;
head.next = temp;
temp = now;
head = nexttemp;
if (head == null){
return temp;
}
}
return null;
}
public static ListNode reverseList(ListNode head) {
if (head == null || head.next == null){
return head;
}
ListNode p = head;
head = reverseList(p.next);
p.next.next = p;
p.next = null;
return head;
}
面试题21:合并两个有序链表
新建一个链表,比较两个链表放入较小值,再将未完的放入; |
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null){
if (l2 == null){
return null;
}else {
return l2;
}
}
if (l2==null){
return l1;
}
ListNode head = new ListNode(-1);
ListNode cur = head;
while (l1!=null && l2!=null){
if (l1.val >= l2.val){
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}else {
cur.next = l1;
cur = cur.next;
l1 =l1.next;
}
}
while (l1 != null){
cur.next = l1;
cur = cur.next;
l1 = l1.next;
}
while (l2 != null){
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
return head.next;
}
面试题234:回文链表
转化为比较前半与后半的问题,首先用快慢指针定位到链表中间,再将后半链表进行翻转,再比较 |
public static boolean isPalindrome(ListNode head) {
if (head == null){
return true;
}else if (head.next == null){
return true;
}
ListNode fast = head;
ListNode slow = head;
while (fast.next!=null && fast.next.next !=null){
slow = slow.next;
fast = fast.next.next;
}
ListNode tail = slow.next;
slow.next = null;
ListNode newhead = new ListNode(-1);
newhead.next = tail;
while (tail.next!=null){
ListNode temp = tail.next;
tail.next = tail.next.next;
temp.next = newhead.next;
newhead.next = temp;
}
newhead = newhead.next;
while (newhead != null){
if (newhead.val != head.val){
return false;
}
newhead = newhead.next;
head = head.next;
}
return true;
}
面试题141:环形链表
快慢指针,如果存在环,最后快指针会追上慢指针 |
public static boolean hasCycle(ListNode head) {
if (head == null || head.next == null){
return false;
}
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
if (slow == fast){
return true;
}
}
return false;
}
面试题104:二叉树的最大深度
递归 |
public static int maxDepth(TreeNode root) {
if (root == null){
return 0;
}else if (root.left == null && root.right == null){
return 1;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return left>right?left+1:right+1;
}
面试题98:验证二叉搜索树
构造函数时需要传入应该大于的数和应该小于的数,每个节点不同。 |
中序遍历为有序序列 |
public static boolean isValidBST(TreeNode root) {
if (root == null) return true;
return valid(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public static boolean valid(TreeNode root, long low, long high) {
if (root == null) return true;
if (root.val <= low || root.val >= high) return false;
return valid(root.left, low, root.val) && valid(root.right, root.val, high);
}
面试题101:对称二叉树
可以定义一种从右子树开始先序遍历方法,与左遍历相比较 |
递归比较左右子树对应位置。迭代可以使用两个栈进行辅助 |
public static boolean isSymmetric(TreeNode root) {
if (root == null){
return true;
}
ArrayList arrayList1 = new ArrayList<>();
ArrayList arrayList2 = new ArrayList<>();
core_1(root,arrayList1);
core_2(root,arrayList2);
System.out.println(arrayList1.toString());
System.out.println(arrayList2.toString());
for (int x = 0;x<=arrayList1.size()-1;x++){
if (arrayList1.get(x)!= arrayList2.get(x)){
return false;
}
}
return true;
}
public static void core_1(TreeNode root,ArrayList arrayList){
if (root == null){
arrayList.add(-1);
return;
}
arrayList.add(root.val);
//
core_1(root.left,arrayList);
core_1(root.right,arrayList);
}
public static void core_2(TreeNode root,ArrayList arrayList){
if (root == null){
arrayList.add(-1);
return;
}
arrayList.add(root.val);
core_2(root.right,arrayList);
core_2(root.left,arrayList);
}
面试题102:二叉树的层次遍历(剑指offer写过)
用两个变量维护本层数量,与下层数量 |
面试题108:将有序数组转化为二叉搜索树
可以用递归构建,每次找到中间的元素作为根 |
public static TreeNode sortedArrayToBST(int[] nums) {
if (nums == null){
return null;
}
TreeNode root = core(nums,0,nums.length-1);
return root;
}
public static TreeNode core(int[] nums,int start,int end){
if (start>end){
return null;
}else if (start == end){
return new TreeNode(nums[start]);
}
int middle = (end-start+1)/2+start;
TreeNode root = new TreeNode(nums[middle]);
TreeNode left = core(nums,start,middle-1);
TreeNode right = core(nums,middle+1,end);
root.left = left;
root.right = right;
return root;
}
面试题88:合并有序数组
依次将nums2的元素插入nums1 |
直接比较nums1和nums2比较大的放入nums1的后面 |
public static void merge(int[] nums1, int m, int[] nums2, int n) {
if (nums1 == null || nums2 == null){
return;
}
if (nums1.length < (m+n) || m<0 || n<0){
return;
}
for (int x = m;x<=m+n-1;x++){
nums1[x] = nums2[x-m];
}
int start1 = 0;
int start2 = m;
while (start1 < start2){
if (start2 > m+n-1){
break;
}
if (nums1[start1] > nums1[start2]){
int temp = nums1[start2];
start2++;
for (int x = start2-2;x>=start1;x--){
nums1[x+1] = nums1[x];
}
nums1[start1] = temp;
start1++;
}else {
start1++;
}
}
}
面试题278:第一个错误的版本
用二分查找边界,当start和end特别大是mid要注意处理 |
public int firstBadVersion(int n) {
if (n<0){
return -1;
}
int start = 1;
int end = n;
int mid = 1;
while (start
面试题70:爬楼梯(剑指offer写过)
f(n) = f(n-1)+f(n+1),用数组将计算过的值存储下来,还可以进一步优化只记录前两个值。 |
面试题121:买卖股票的最佳时机(剑指offer写过)
维护到当前元素为止出现过的最小值与最大利润 |
public static int maxProfit(int[] prices) {
if (prices == null || prices.length <=1){
return 0;
}
int[] lowprice = new int[prices.length];
lowprice[0] = prices[0];
for (int x = 1;x<=prices.length-1;x++){
lowprice[x] = lowprice[x-1] > prices[x-1] ? prices[x-1]:lowprice[x-1];
}
int maxprofit = 0;
for (int x = 0;x<=prices.length-1;x++){
if (prices[x]-lowprice[x]>maxprofit){
maxprofit = prices[x]-lowprice[x];
}
}
return maxprofit;
}
面试题53:最大子序和
动态规划,维护最大值 |
分治,递归,将数组分为前后两部分,分别求最大值,以及从中间向两边的最大值 |
public static int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}else if (nums.length == 1){
return nums[0];
}
int sum = 0;
int max = nums[0];
for (int x = 0; x<=nums.length-1;x++){
sum = sum+nums[x];
if (sum>max){
max = sum;
}
if (sum < 0){
sum = 0;
}
}
return max;
}
面试题198:打家劫舍
f(n) = max{f(n-1), f(n-2)+nums[n]};初始化时,需要初始化0,1位置,f的意思是到n时不相邻数能产生的最大和。 |
public static int rob(int[] nums) {
if (nums == null || nums.length == 0){
return 0;
}else if (nums.length == 1){
return nums[0];
}
int[] profits = new int[nums.length];
profits[0] = nums[0];
profits[1] = nums[1];
if (nums.length == 2){
return Math.max(profits[0],profits[1]);
}
for (int x = 2;x<=nums.length-1;x++){
int max = 0;
for (int y = 0;y<=x-2;y++){
if (profits[y] > max){
max = profits[y];
}
}
profits[x] = Math.max(max+nums[x],profits[x-1]);
}
return profits[nums.length-1];
}
面试题384:打乱数组
遍历数组,为当前位置生成一个随机位置(向后),交换 |
生成一个数组长度的随机数数组,避免重复,再根据下标获取位置。 |
class Solution {
private int[] origin;
public Solution(int[] nums) {
this.origin = nums.clone();
}
/** Resets the array to its original configuration and return it. */
public int[] reset() {
return this.origin;
}
/** Returns a random shuffling of the array. */
public int[] shuffle() {
int lenth = origin.length;
int[] order = new int[lenth];
int num;
int count = 0;
boolean flag = false;
while (count
面试题155:最小栈(剑指offer)
再用一个栈维护最小值 |
分情况处理即可 |
public static List fizzBuzz(int n) {
List reback = new ArrayList<>();
if (n<=0){
return reback;
}
for (int x = 1;x<=n;x++){
if (x%15 == 0){
reback.add("FizzBuzz");
}else if (x%3 == 0){
reback.add("Fizz");
}else if (x%5 == 0){
reback.add("Buzz");
}else {
reback.add(x+"");
}
}
return reback;
}
面试题204:计数质数
用标记矩阵,从0-n/2(答案是sqrt(n)),如果当前标记为false,则将其倍数都标记为true,最终再遍历一次数组,得到为false的次数 |
class Solution {
public static int countPrimes(int n) {
if (n<=2){
return 0;
}
boolean[] ifnum = new boolean[n-2];
int sum = 0;
int limit = n/2;
for (int i = 2;i<=limit;i++){
if (ifnum[i-2] == false){
for (int j = i*2;j
题目326:3的幂
不能用循环的时候可以用对数函数检查 |
public static boolean isPowerOfThree(int n) {
if (n == 1){
return true;
}
if (n<=2){
return false;
}else if (n%2 == 0){
return false;
}
double re = Math.log10(n)/Math.log10(3);
if ((re-(int)re)==0){
return true;
}else {
return false;
}
}
面试题13:罗马数字转整数
规则表示如果当前数小于后一位数则减去当前数,否则加上此位,这种方法只需要遍历字符串一遍 |
将特殊的替换了过后,全部相加 |
public static int romanToInt(String s) {
if (s == null || s.length() == 0){
return 0;
}
HashMap hashMap = new HashMap<>();
s = s.replace("IV","1");
hashMap.put('1',4);
s = s.replace("IX","2");
hashMap.put('2',9);
s = s.replace("XL","3");
hashMap.put('3',40);
s = s.replace("XC","4");
hashMap.put('4',90);
s = s.replace("CD","5");
hashMap.put('5',400);
s = s.replace("CM","6");
hashMap.put('6',900);
hashMap.put('I',1);
hashMap.put('V',5);
hashMap.put('X',10);
hashMap.put('L',50);
hashMap.put('C',100);
hashMap.put('D',500);
hashMap.put('M',1000);
int sum = 0;
for (char x : s.toCharArray()){
if (hashMap.containsKey(x)){
sum += hashMap.get(x);
}else {
return -1;
}
}
return sum;
}
面试题191:位1的个数
按位与1,然后移位比较 |
public static int hammingWeight(int n) {
int start = 1;
int count = 0;
int num = 0;
while (count<=30){
if ((start&n) == start ){
num++;
}
start = start<<1;
count++;
}
return num;
}
面试题461:汉明距离
按位异或后统计为1的位数,统计为1的位数可以用n&(n-1)的次数来进行计算 |
public static int hammingDistance(int x, int y) {
if (x<0||y<0){
return -1;
}
int yihuo = x^y;
int start = 1;
int count = 0;
int sum = 0;
while (count<=30){
if ((start&yihuo) == start){
sum++;
}
start = start<<1;
count++;
}
return sum;
}
面试题190:颠倒二进制位
从原数的低位开始,用一个新的变量来存,每读一位分别左移和右移 |
public static int reverseBits(int n) {
int ans = 0;
for (int x = 0;x<=31;x++){
ans = ans <<1;
if ((n&1) == 1){
ans += 1;
}
n = n>>1;
}
return ans;
}
面试题118:杨辉三角
利用上一行算出下一行 |
public static List> generate(int numRows) {
List> lists = new LinkedList<>();
if (numRows<=0){
return lists;
}
List level = new ArrayList<>();
level.add(1);
List temp = new ArrayList<>();
for (int x:level){
temp.add(x);
}
lists.add(temp);
if (numRows == 1){
return lists;
}
for (int x = 2;x<=numRows;x++){
// System.out.print(level);
level.add(0,0);
level.add(level.size(),0);
List nexline = new ArrayList<>();
for (int y = 0;y<=level.size()-2;y++){
nexline.add(level.get(y)+level.get(y+1));
}
List add = new ArrayList<>();
level.clear();
for (int z:nexline){
add.add(z);
level.add(z);
}
// System.out.print(add);
lists.add(add);
}
return lists;
}
面试题20:有效的括号
用栈辅助,前半个括号进栈,读到后半个括号时取出查看是否为对应的 |
public static boolean isValid(String s) {
if (s == null || s.length() == 0){
return true;
}
Stack stack = new Stack<>();
for (char x :s.toCharArray()){
if (x == '(' || x == '[' || x =='{'){
stack.push(x);
}
if (x == ')'){
if (stack.size() == 0){
return false;
}
char temp = stack.pop();
if (temp!='('){
return false;
}
}
if (x == ']'){
if (stack.size() == 0){
return false;
}
char temp = stack.pop();
if (temp!='['){
return false;
}
}
if (x == '}'){
if (stack.size() == 0){
return false;
}
char temp = stack.pop();
if (temp!='{'){
return false;
}
}
}
if (stack.size()!=0){
return false;
}
return true;
}
面试题268:缺失数字
利用数组的和和现在的和的差值 |
利用与0-n的数的异或 |
public static int missingNumber(int[] nums) {
if (nums == null||nums.length == 0){
return -1;
}
int sum = (0+nums.length)*(nums.length+1)/2;
int nowsum = 0;
for (int x:nums){
nowsum += x;
}
return sum - nowsum;
}