【方法】
字写大点,先注释框架
//corner case
if (headA == null || headB == null) {
return null;
}
//keep the same length
int A_len = getLength(headA);
int B_len = getLength(headB); while (A_len > B_len) {
headA = headA.next;
A_len--;
}
while (A_len < B_len) {
headB = headB.next;
B_len--;
}
//find the same node
while (headA != headB) {
headA = headA.next;
headB = headB.next;
}
LCA:用两个点和要找的方向来DC
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
if (root == null || A == root || B == root) {//
return root;
}
//divide
TreeNode left = lowestCommonAncestor(root.left, A, B);
TreeNode right = lowestCommonAncestor(root.right, A, B); //conquer
if (left != null && right != null) {
return root;//
}
else if (left != null) {
return left;
}
else if (right != null) {
return right;
}
else {
return null;
}
}
diameter of tree树的周长
public int depth(TreeNode root) {
//corner case
if (root == null) {
return 0;
}
//define left, right
int left = depth(root.left);
int right = depth(root.right);
//renew max, don't add 1 since it's a sum of two lines
max = Math.max(max, left + right);
//return val for root, notice
return Math.max(left, right) + 1;
}
对称的树:先判断相等
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
//corner case
if (s == null) {
return false;
}
if (isSame(s,t)) {
return true;
}
return isSubtree(s.left, t) || isSubtree(s.right, t);
} public boolean isSame(TreeNode s, TreeNode t) {
//both null
if (s == null && t == null) {
return true;
}
//one is null
if (s == null || t == null) {
return false;
}
//false
if (s.val != t.val) {
return false;
}
//default
return isSame(s.left, t.left) && isSame(s.right, t.right);
}
}
同时要判断平衡和深度,自定义新的数据类型:
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/ public class Solution {
/*
* @param root: The root of binary tree.
* @return: True if this Binary tree is Balanced, or false.
*/
class ResultType {
boolean isBalanced;
int maxDepth;
ResultType(boolean isBalanced,int maxDepth) {
this.isBalanced = isBalanced;
this.maxDepth = maxDepth;
}
}; public boolean isBalanced(TreeNode root) {
return helper(root).isBalanced;
} private ResultType helper (TreeNode root) {
if (root == null) {
return new ResultType(true, 0);
} ResultType left = helper(root.left);
ResultType right = helper(root.right); if (!left.isBalanced || !right.isBalanced) {
return new ResultType(false, - 1);
} else if (Math.abs(left.maxDepth - right.maxDepth) > 1) {
return new ResultType(false, - 1);
}
else {
return new ResultType(true, Math.max(left.maxDepth,right.maxDepth) + 1);
}
}
}
Binary Tree Paths 用iteration
void findBT(TreeNode root, String path, List<String> ans) {
if (root.left == null && root.right == null)
ans.add(path + root.val);//add here since it's an sign of end
if (root.left != null) findBT(root.left, path + root.val + "->"参数是path,每次新加一个节点, ans);
if (root.right != null) findBT(root.right, path + root.val + "->", ans);
}
merge binary tree
class Node
{
int data;
Node left, right; public Node(int data, Node left, Node right) {
this.data = data;
this.left = left;
this.right = right;
} /* Helper method that allocates a new node with the
given data and NULL left and right pointers. */
static Node newNode(int data)
{
return new Node(data, null, null);
} /* Given a binary tree, print its nodes in inorder*/
static void inorder(Node node)
{
if (node == null)
return; /* first recur on left child */
inorder(node.left); /* then print the data of node */
System.out.printf("%d ", node.data); /* now recur on right child */
inorder(node.right);
} /* Method to merge given two binary trees*/
static Node MergeTrees(Node t1, Node t2)
{
if (t1 == null)
return t2;
if (t2 == null)
return t1;
t1.data += t2.data;
t1.left = MergeTrees(t1.left, t2.left);
t1.right = MergeTrees(t1.right, t2.right);
return t1;
}
class Solution {
public boolean containsDuplicate(int[] nums) {
//cc
if (nums.length == 0 || nums == null) {
return false;
}
//ini = sort
Arrays.sort(nums);记得先排序
//for
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1]) {
直接return true;
}
}
return false;
}
}
class Solution {
public int titleToNumber(String s) {
int res = 0;
for (int i = 0; i < s.length(); i++) {
26进制
res = res * 26 + (s.charAt(i) - 'A' + 1);
}
return res;
}
}
2的倍数,三种方法:
Last Edit: October 22, 2018 8:24 PM motorix
motorix
260
This question is not an difficult one, and there are many ways to solve it. Method 1: Iterative check if n can be divided by 2. If yes, divide n by 2 and check it repeatedly. if (n == 0) return false;
while (n%2 == 0) n/=2;
return n == 1;
Time complexity = O(log n) Method 2: Recursive return n > 0 && (n == 1 || (n%2 == 0 && isPowerOfTwo(n/2)));
Time complexity = O(log n) Method 3: Bit operation If n is the power of two: n = 2 ^ 0 = 1 = 0b0000...00000001, and (n - 1) = 0 = 0b0000...0000.
n = 2 ^ 1 = 2 = 0b0000...00000010, and (n - 1) = 1 = 0b0000...0001.
n = 2 ^ 2 = 4 = 0b0000...00000100, and (n - 1) = 3 = 0b0000...0011.
n = 2 ^ 3 = 8 = 0b0000...00001000, and (n - 1) = 7 = 0b0000...0111.
we have n & (n-1) == 0b0000...0000 == 0 Otherwise, n & (n-1) != 0. For example, n =14 = 0b0000...1110, and (n - 1) = 13 = 0b0000...1101. return n > 0 && ((n & (n-1)) == 0);
Time complexity = O(1)
二进制中1的个数 往右移动获得数字
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int ones = 0;
while (n != 0) {
ones += (n & 1);
n = n >>> 1;
}
return ones;
}
}
3.变换符号
变换符号就是正数变成负数,负数变成正数。
如对于-11和11,可以通过下面的变换方法将-11变成11
1111 0101(二进制) –取反-> 0000 1010(二进制) –加1-> 0000 1011(二进制)
同样可以这样的将11变成-11
0000 1011(二进制) –取反-> 0000 0100(二进制) –加1-> 1111 0101(二进制)
因此变换符号只需要取反后加1即可
找两个字符串的区别:用异或就对了
class Solution {
public char findTheDifference(String s, String t) {
char c = 0;
for (int i = 0; i < s.length(); ++i) {
c ^= s.charAt(i);
}
for (int i = 0; i < t.length(); ++i) {
c ^= t.charAt(i);
}
return c;
}
}
连续自然数数组中缺失的数字 :异或2次
//268. Missing Number
//for loop, judge if nums[i + 1] != nums[i] + 1
class Solution {
public int missingNumber(int[] nums) { //xor
int res = nums.length;
System.out.println(" res = " + res); for(int i=0; i<nums.length; i++){
System.out.println(" i = " + i);
System.out.println(" nums[i] = " + nums[i]); res ^= i;
System.out.println(" res ^= i = " + res);
res ^= nums[i];
System.out.println(" res ^= nums[i] = " + res);
System.out.println(" ");
}
return res;
}
}
//n 1
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int ones = 0;
while (n != 0) {
计算每一位数与1的结果
ones += (n & 1);
n = n >>> 1;
}
return ones;
}
}
public class Solution {
/**
* @param root: The root of binary tree.
* @return: An integer.
*/
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
} int left = maxDepth(root.left);
int right = maxDepth(root.right); int max = Math.max(left,right);
return max + 1;
}
}
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
//TreeNode node = new TreeNode(0);
//corner case
if (nums.length == 0) {
return null;
}
TreeNode node = helper(nums, 0, nums.length - 1);// -1 should be noticed ahead
return node;
}
必须要有三个参数,不同的函数才能被称作helper
public TreeNode helper(int[] nums, int low, int high) {
//corner case : low > high
if (low > high) {
return null;
}
int mid = low + (high - low) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = helper(nums, low, mid - 1);
root.right = helper(nums, mid + 1, high);
要用到函数里给的参数
return root;
}
}
118. Pascal's Trianglclass Solution
public List<List<Integer>> generate(int numRows)
//ini
List<List<Integer>> triangle = new ArrayList<List<Integer>>(); //cc
if (numRows <= 0) return triangle; //for
for (int i = 0; i < numRows; i++) {
List<Integer> row = new ArrayList<Integer>(); for (int j = 0; j < i + 1; j++) {
//首先写corner case
if (j == 0 || j == i) {
row.add(1);
}else {
row.add(triangle.get(i - 1).get(j - 1) + triangle.get(i - 1).get(j));
}
}
//add again
用add方法
triangle.add(new ArrayList(row));
} //return
return triangle;
}
}
plusOne 数组加一,从最后开始进位
public class Solution {
/**
* @param digits: a number represented as an array of digits
* @return: the result
*/
public int[] plusOne(int[] digits) {
//not carry
int n = digits.length;
//0 to n-1 whenever
for (int i = n - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++;
return digits;直接在这里return即可
}else {
digits[i] = 0;
}
}
//carry, need new array
int[] answer = new int[n + 1];
answer[0] = 1;
return answer;
}
}
deleteNode
public class Solution {
/*
* @param node: the node in the list should be deletedt
* @return: nothing
*/
public void deleteNode(ListNode node) {
// write your code here
if (node == null || node.next == null) {
return ;
}
注意删除的是next而不是当前的node
ListNode next = node.next;
node.val = next.val;
node.next = next.next;
}
}
190. Reverse Bits
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
//ini res
int res = 0; //for loop: 32 32位数,做移动32次
for (int i = 0; i < 32; i++) {
res <<= 1; 左移留出最后一位为0来相加
if ((n & 1) == 1) res += 1;
n >>= 1; 右移留出最后一位来操作
} return res;
}
}
101. Symmetric Tree
class Solution {
public boolean isSymmetric(TreeNode root) {
//corner case
if (root == null) {
return true;
}
return isSymmetricHelper(root.left, root.right);
} public boolean isSymmetricHelper(TreeNode left, TreeNode right) {
//all null
if (left == null && right == null) {
return true;
}
//one null
if (left == null || right == null) {
return false;
}
//not same
if (left.val != right.val) {
return false;
}
//same
return isSymmetricHelper(left.left, right.right) && isSymmetricHelper(left.right, right.left);
//don't forget the function name
}
}
234. Palindrome Linked List 两边开始
public class Solution {
/**
* @param head: A ListNode.
* @return: A boolean.
*/
public boolean isPalindrome(ListNode head) {
// corner case
if (head == null) {
return true;//true
}
//p1 go with p2
ListNode middle = findMiddle(head);
middle.next = reverse(middle.next);// ListNode p1 = head, p2 = middle.next;
while (p2 != null && p1.val == p2.val) {//order
p1 = p1.next;
p2 = p2.next;
}
return p2 == null;
} private ListNode findMiddle(ListNode head) {
// corner case
if (head == null) {
return null;
}无处不在的corner case
ListNode fast = head.next, slow = head; 先走一步
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
} private ListNode reverse(ListNode head) {
// corner case
if (head == null) {
return null;
}
ListNode prev = null;
while (head != null) {
ListNode temp = head.next;
head.next = prev;
prev = head;
head = temp;
}
return prev;
}
}
136. Single Number 出现一次 用异或
class Solution {
public int singleNumber(int[] nums) {
//ini n
int n = 0; //for loop ^=
for (int i = 0; i < nums.length; i++) {
n ^= nums[i]; 不同2次会返回原来的值
} //return
if (n != 0) return n; return 0;
}
}
169. Majority Element(n/2 times)
class Solution {
public int majorityElement(int[] nums) {
//ini
int major = nums[0];
int count = 1;
//1 - n
for (int i = 1; i < nums.length; i++) {
//nums[i] != major, count--,if count == 0
if (nums[i] != major) {
if (count == 0) {
major = nums[i];
count++;
}
count--;抵消当前的
}else {
//nums[i] == major, count++
count++;
}
}
return major;
}
}
160. Intersection of Two Linked Lists 想想图,对着写就行了
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
public class Solution {
/*
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//corner case
if (headA == null || headB == null) {
return null;
}
//keep the same length
int A_len = getLength(headA);
int B_len = getLength(headB); while (A_len > B_len) {
headA = headA.next;
A_len--;
}
while (A_len < B_len) {
headB = headB.next;
B_len--;
}
//find the same node
while (headA != headB) {
headA = headA.next;
headB = headB.next;
} return headA;
} //getLength
public int getLength(ListNode node) {
int length = 0;
while(node != null) {
length++;
node = node.next;
}
return length;
}
}
26. Remove Duplicates from Sorted Array
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int size = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != nums[size]) { 总是去和size代表的最后一位相比较
nums[++size] = nums[i];
}
}
return size + 1;剩一个0位
}
}
387. First Unique Character in a String
public class Solution {
/**
* @param s: a string
* @return: it's index
*/
public int firstUniqChar(String s) {
//corner case
if (s == null) {
return 0;
}
//put into cnt[]
char[] c = s.toCharArray();字母是一个单独的数组
int[] cnt = new int[256];表示所有字符
for (int i = 0; i < s.length(); i++) {
cnt[c[i]]++;
}
//return
for (int i = 0; i < s.length(); i++) {
if (cnt[c[i]] == 1) {
return i;
//break;
}
}
return -1;
}
}
14. Longest Common Prefix
Input: ["flower","flow","flight"]
Output: "fl"
public class Solution {
/**
* @param strs: A list of strings
* @return: The longest common prefix
*/
public String longestCommonPrefix(String[] strs) {
//corner case
if (strs == null) {
return "";
}
if (strs.length == 0) {
return "";
}
//define pre
String pre = strs[0];
int n = strs.length;
//shorten pre
for (int i = 1; i < n; i++) {
while (strs[i].indexOf(pre) != 0) {
pre = pre.substring(0, pre.length() - 1);
}
}
//return
return pre;
}
}
283. Move Zeroes
class Solution {
public void moveZeroes(int[] nums) {
//cc
if (nums == null || nums.length == 0) return;
//ini
int insertPos = 0; for (int num : nums) {
//no 0s
if (num != 0) {
nums[insertPos++] = num;
}
}
//0s 分开就行
while (insertPos < nums.length) {
nums[insertPos++] = 0;
}
//return
}
}
//88. Merge Sorted Array
//add the bigger number from backward 从后往前
public class Solution {
/*
* @param A: sorted integer array A which has m elements, but size of A is m+n
* @param m: An integer
* @param B: sorted integer array B which has n elements
* @param n: An integer
* @return: nothing
*/
public void merge(int[] A, int m, int[] B, int n) {
// write your code here
int index = m + n - 1;
int i = m - 1;
int j = n - 1;
//add the bigger number from backward
while (i >= 0 && j >= 0) {最重要的是这一步
if (A[i] > B [j]) {
A[index--] = A[i--];
}
else {
A[index--] = B[j--];
}
}
//if there's number remaning in just A or B, append to the result
while (i >= 0) {
A[index--] = A[i--];
}
while (j >= 0) {
A[index--] = B[j--];
}
}
}
Merge Two Sorted Lists 从前往后
public class Solution {
/*
* @param l1: ListNode l1 is the head of the linked list
* @param l2: ListNode l2 is the head of the linked list
* @return: ListNode head of linked list
*/
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// write your code here
ListNode dummy = new ListNode(0);
ListNode tail = dummy;得用dummy node
while(l1 != null && l2 != null) {
if (l1.val < l2.val) {
tail.next = l1;
l1 = l1.next;
}
else {
tail.next = l2;
l2 = l2.next;
}
tail = tail.next;一样的,注意要有主变量
}
if (l1 != null) {
tail.next = l1;
}
if (l2 != null) {
tail.next = l2;
}
return dummy.next;
}
}
121. Best Time to Buy and Sell Stock
//121. Best Time to Buy and Sell Stock
//use greedy to solve
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0 || prices == null) {
return 0;
} int min = Integer.MAX_VALUE;
int profit = 0;
//update the min price and the max profit each time
for (int i = 0; i < prices.length; i++) {
两个三元运算符
min = min < prices[i] ? min : prices[i];
profit没有i = (prices[i] - min) > profit ? prices[i] - min : profit;
} return profit;
}
}
//n 1
Reverse Integer: 我不熟悉的对每一位数进行的操作,步骤都是:取数、迭代、改数
public int reverse(int x) {
//ini
int res = 0, newRes = 0; while (x != 0) {
int tail = x % 10;先余后除,中间是newres 先背吧
newRes = res * 10 + tail;
if ((newRes - tail) / 10 != res) {
return 0;
}
res = newRes;
x = x / 10;
} //return
return newRes;
}
Maximum Subarray
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 0 || nums == null) {
return -1;
} int sum = 0;
int minSum = 0;
int max = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
max = Math.max(max, sum - minSum);先减之前的
minSum = Math.min(minSum, sum);
} return max;
}
}
Two Sum
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i = 0; i < nums.length; i++) {
if (map.containsKey(target - nums[i])) {
result[0] = map.get(target - nums[i]);模板index
result[1] = i; return result;
}
map.put(nums[i],i);
}
return result;
}
}
Linked List Cycle
public class Solution {
/*
* @param head: The first node of linked list.
* @return: True if it has a cycle, or false
*/
public boolean hasCycle(ListNode head) {
// write your code here
if (head == null) {
return false;
}
ListNode fast = head.next;
ListNode slow = head;
while(fast != slow) {
if (fast == null || fast.next == null) {
return false;
}
fast = fast.next.next;
slow = slow.next;
} return true;
}
}
Add Two Numbers 从前往后加,carry在最后面
public class Solution {
/*
* @param l1: the first list
* @param l2: the second list
* @return: the sum list of l1 and l2
*/
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//intialize
ListNode dummy = new ListNode(0);
ListNode tail = dummy;//
//sum
int carry = 0;
for (ListNode i = l1, j = l2; i != null || j != null;) {
int sum = carry;
sum += (i != null)? i.val: 0;注意一下是否为空再加
sum += (j != null)? j.val: 0;
// %
tail.next = new ListNode(sum % 10);
tail = tail.next;
// /
carry = sum / 10;
i = (i == null)? i : i.next;//i, j should go down
j = (j == null)? j : j.next;//judge itself
}
//carry 用于最后结尾收尸
if (carry != 0) {
tail.next = new ListNode(carry);
}//turn carry into a node return dummy.next;//forget
}
}
万年不会的翻转链表
class Solution {
public ListNode reverseList(ListNode head) { ListNode prev = null;
ListNode curt = head; while(curt != null) {
ListNode temp = curt.next;
curt.next = prev;
prev = curt;
curt = temp;
}
return prev;
}
}
1. 找两个array不同的element: 就用双重for循环,没有啥高级的办法,就这样!
public static void main(String[] args) {
// TODO Auto-generated method stub int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6 };
int[] arr2 = new int[] { 5, 6, 7, 8 }; boolean contains = false;
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
contains = true;
break;
}
} if(!contains){
list.add(arr1[i]);
}
else{
contains = false;
}
}
System.out.println(list); }
2. 怎么实现hashmap,big O是多少
key- index - bucket[index] array
private int getBucketIndex(K key)
{
int hashCode = key.hashCode();
int index = hashCode % numBuckets;
return index;
}
好像不一样,不用看了
public class Book implements Comparable<Book>{
String title, author; int year;
Book(String title, String author, int year) {
//the usual stuff
}
@Override
public int compareTo(Book b) {
return (this.title.compareTo(b.title));
}
@Override
public int hashCode() {
return Objects.hash(title, author, year);
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (getClass() != o.getClass()) return false;
Book b = (Book) o;
return title.equals(b.title)
&& author.equals(b.author)
&& (year == b.year);
}}
3. friend circle
class Solution {
public int findCircleNum(int[][] M) {
//corner case
if (M == null || M.length == 0) return 0; //initialization: count = n, each id = id
int m = M.length;
int count = m;
int[] roots = new int[m];
for (int i = 0; i < m; i++) roots[i] = i; //for loop and union find
for (int i = 0; i < m; i++) {
for (int j = i + 1; j < m; j++) {
//if there is an edge, do union find
if (M[i][j] == 1) {
//注意下是怎么来的
int root0 = find (roots, i);
int root1 = find (roots, j); if (root0 != root1) {
roots[root1] = root0;
count--;
}
}
}
} //return count
return count;
} public int find (int[] roots, int id) {
while (id != roots[id]) {
id = roots[roots[id]];
}
return id;
}
}
4. 找array倒数第k个element;找array连续element前面的element
只让我写了一个sql和一个merge sort...我觉得那不算算法题
mergesort: 新建两个数组,recursively merge之后再拼起来
//recursive and append
public static void mergeSort(int[] a, int n) {
if (n < 2) {
return;
}
int mid = n / 2;
int[] l = new int[mid];
//不一定是双倍,要用n-mid
int[] r = new int[n - mid]; for (int i = 0; i < mid; i++) {
l[i] = a[i];
}
for (int i = mid; i < n; i++) {
r[i - mid] = a[i];
//for loop里就不用++了
}
//sort - merge
mergeSort(l, mid);
mergeSort(r, n - mid); merge(a, l, r, mid, n - mid);
} public static void merge(
int[] a, int[] l, int[] r, int left, int right) {
//list 5 variables here
int i = 0, j = 0, k = 0;
while (i < left && j < right) {
if (l[i] < r[j]) {
a[k++] = l[i++];
}
else {
a[k++] = r[j++];
}
}
//should be outside
while (i < left) {
a[k++] = l[i++];
}
while (j < right) {
a[k++] = r[j++];
}
}
quicksort:移动index, index还是原来的i < j就得交换后继续
package com.java2novice.sorting; public class MyQuickSort { private int array[];
private int length; public void sort(int[] inputArr) { if (inputArr == null || inputArr.length == 0) {
return;
}
this.array = inputArr;
length = inputArr.length;
quickSort(0, length - 1);
} private void quickSort(int lowerIndex, int higherIndex) { int i = lowerIndex;
int j = higherIndex;
// calculate pivot number, I am taking pivot as middle index number
int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
pivot应该是数组中的一个元素
// Divide into two arrays
//写完i j的关系之后要写整个数组的recursive
while (i <= j) {
/**
* In each iteration, we will identify a number from left side which
* is greater then the pivot value, and also we will identify a number
* from right side which is less then the pivot value. Once the search
* is done, then we exchange both numbers.
*/
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
//array[i] is bigger than pivot, so exchange and continue
if (i <= j) {
exchangeNumbers(i, j);
//move index to next position on both sides
i++;
j--;
}
}
// call quickSort() method recursively
if (lowerIndex < j)
quickSort(lowerIndex, j);
if (i < higherIndex)
quickSort(i, higherIndex);
} private void exchangeNumbers(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} public static void main(String a[]){ MyQuickSort sorter = new MyQuickSort();
int[] input = {24,2,45,20,56,75,2,56,99,53,12};
sorter.sort(input);
for(int i:input){
System.out.print(i);
System.out.print(" ");
}
}
}
说给100首歌,设计一个shuffle/repeat播放音乐的逻辑.本文原创自1point3acres论坛
没有写代码,就说了说思路,也并不在乎你用啥语言,我用的python问能不能用buildin func 或者numpy都允许了hhh.
就用numpy random一个整数范围是0~n然后每次放了这个歌以后直接把这条数据移到最后然后n-1就行,最后n=1的时候播放最后一首歌,同时n再置最开始的那个数值就好。感觉这题是现场出的,说是考数据结构我一开始想用map,还迂回了很久= =。希望不要觉得我笨
【valid parenthesis】
class Solution {
public boolean isValid(String s) {
//corner case
if (s == null) {
return true;
}
Stack<Character> stack = new Stack<Character>();
//push into stack
for (char c : s.toCharArray()) {
//left cases
if (c == '(') {
stack.push(')');
}else if (c == '[') {
//每一种都要写
stack.push(']');
}else if (c == '{') {
stack.push('}');
}else if (stack.isEmpty() || stack.pop() != c) {
//right case
return false;
}
}
return stack.isEmpty();
}
}
【invert binary tree】
class TreeNode {
int val; TreeNode left, right; //parameter is another item
TreeNode(int item) { val = item; left = right = null; }}
class Solution {
public TreeNode invertTree(TreeNode root) {
//careful with corner case
if (root == null) {
return null;
}
TreeNode temp = root.left;
root.left = invertTree(root.right);
root.right = invertTree(temp);
return root;
}
}
【给两个String,找相同的字符】就是双重for循环
public static void main(String[] args) {
String str1 = "刘烨,孙坚,王二小,蜘蛛侠,钢铁侠,毛剑卿";
String str2 = "王二小,李占军,刘胡兰,毛剑卿";
String[] arr1 = str1.split(",") ;
String[] arr2 = str2.split(",") ;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr2.length; i++){
for (int j = 0; j < arr1.length; j++){
if (arr1[j].equals(arr2[i])){
sb.append(arr1[j] + ",") ;
}
}
}
System.out.println("结果:" + sb.toString().substring(0, sb.toString().length() - 1));
}
【reverse vowels】典型双指针了
class Solution {
public String reverseVowels(String s) {
//cc
if (s == null) {
return s;
}
//ini
String vowels = "aeiouAEIOU";
char[] chars = s.toCharArray();
int start = 0, end = s.length() - 1;
while (start < end) {
//adjust start, end
while (start < end && !vowels.contains(chars[start] + "")) {
start++;
}
while (start < end && !vowels.contains(chars[end] + "")) {
end--;
}
//exchange
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
//push to move on
start++;
end--;
}
//return
return new String(chars);
}
}
【missing number】短路了吧?
class Solution {
public int missingNumber(int[] nums) {
//ini = sort
Arrays.sort(nums);
//cc
if (nums[0] != 0) {
return 0;
}
//for
for (int i = 0; i < nums.length - 1; i++) {
//notice
if (nums[i + 1] != nums[i] + 1) {
return nums[i] + 1;
}
}
//return
return nums.length;
}
}
【reverse string】
class Solution {
public String reverseString(String s) {
//corner case
if (s == null) {
return null;
}
int i = 0, j = s.length() - 1;
//convert to char[]
char[] chars = s.toCharArray();
while (i < j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
//notice here
i++;
j--;
}
//convert again
return new String(chars);
//return
}
}
【方法2】
public class Solution {
public String reverseString(String s) {
return new StringBuilder(s).reverse().toString();
}
}
【Valid Palindrome】
public class Solution {
/**
* @param s: A string
* @return: Whether the string is a valid palindrome
*/
public boolean isPalindrome(String s) {
//cc
if (s.isEmpty()) {
return true;
}
//define
int head = 0, tail = s.length() - 1;
while (head < tail) {
char cHead = s.charAt(head), cTail = s.charAt(tail);
//judge:punction or not
if (!Character.isLetterOrDigit(cHead)) {
head++;
}else if (!Character.isLetterOrDigit(cTail)) {
tail--;
}else {
//tolowercase and judge
if (Character.toLowerCase(cHead) != Character.toLowerCase(cTail)) {
return false;
}
//continue
head++;
tail--;
}
}
//return
return true;
}
【二分法解根号2】
class Solution {
public int mySqrt(int x) {
//bs
long start = 1, end = x;
while (start + 1 < end) {
long mid = start + (end - start) / 2;
if (mid * mid <= x) {
start = mid;
}else {
end = mid;
}
}
//return end or start
if (end * end <= x) {
return (int)end;
}
return (int)start;
}
}
【斐波那契数列 recursion】
//Fibonacci Series using Recursion
class fibonacci
{
static int fib(int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential.
【Use Dynamic Programming】
// Fibonacci Series using Dynamic Programming
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+2]; // 1 extra to handle case, n = 0
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
//n n
【井字棋】
public class TicTacToe {
private int[] rows;
private int[] cols;
private int diagonal;
private int antiDiagonal;
/** Initialize your data structure here. */
public TicTacToe(int n) {
rows = new int[n];
cols = new int[n];
}
/** Player {player} makes a move at ({row}, {col}).
@param row The row of the board.
@param col The column of the board.
@param player The player, can be either 1 or 2.
@return The current winning condition, can be either:
0: No one wins.
1: Player 1 wins.
2: Player 2 wins. */
public int move(int row, int col, int player) {
int toAdd = player == 1 ? 1 : -1;
rows[row] += toAdd;
cols[col] += toAdd;
if (row == col)
{
diagonal += toAdd;
}
if (col == (cols.length - row - 1))
{
antiDiagonal += toAdd;
}
int size = rows.length;
if (Math.abs(rows[row]) == size ||
Math.abs(cols[col]) == size ||
Math.abs(diagonal) == size ||
Math.abs(antiDiagonal) == size)
{
return player;
}
return 0;
}
}
【happy number】
class Solution {
public boolean isHappy(int n) {
//cc
if (n == 0) {
return false;
}
//ini
int squareSum, remain;
Set set = new HashSet();
//while loop, contains
//每个n 在set中只加一次,不重复
while (set.add(n)) {
squareSum = 0;
//每次加一个n,都重新算squareSum
while (n > 0) {
remain = n % 10;
squareSum += remain * remain;
n = n / 10;
}
if (squareSum == 1) return true;
n = squareSum;最后才把数字给n
}
return false;
}
}
【number permutation】
public class Solution {
/*
* @param nums: A list of integers.
* @return: A list of permutations.
*/
public List<List<Integer>> permute(int[] nums) {
//corner case
List<List<Integer>> results = new ArrayList<>();//
List<Integer> permutations = new ArrayList<Integer>();
HashSet<Integer> set = new HashSet<Integer>();
if (nums == null) {
return results;
}
if (nums.length == 0) {
results.add(new ArrayList<Integer>());
return results;
}
//helper
helper(nums, permutations, set, results);
return results;
}
//helper :NSTRS
public void helper(int[] nums, int start, List<Integer> temp, List<List<Integer>> results,HashSet<Integer> set用于检验重复) {
if (permutations.size() == nums.length) {//exit
results.add(new ArrayList<Integer>(permutations));
return ; 记得此处要返回,有return
}
for (int i = 0; i < nums.length; i++) {
//continue when there is duplicate 注意重复的情况,这也是一种corner case
if (set.contains(nums[i])) {
continue;
}
temp.add(nums[i]);
set.add(nums[i]);
helper(nums, i+1, temp, results, set);
set.remove(nums[i]);
temp.remove(temp.size() - 1);
}
}
位运算
public ArrayList<String> permute(char[] s, ArrayList<String> list, int index) { list.add(String.valueOf(s));
if (index >= s.length)
return list; for (int i = index; i < s.length; i++) { if (Character.isAlphabetic(s[i])) { s[i] ^= 32;
permute(s, list, i + 1);
s[i] ^= 32;
}
}
return list; }
subset:
private void backtrack(int [] nums, int start,List<Integer> tempList, List<List<Integer>> list){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
【search in 2 2D array】
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0) {
return false;
}
if (matrix[0] == null || matrix[0].length == 0) {
return false;
}
int m = matrix.length;
int n = matrix[0].length;
int x = m - 1;
int y = 0;
int count = 0;
while (x >= 0 && y < n) {
if (matrix[x][y] > target) {
大动
x--;
}
else if(matrix[x][y] < target) {
小动
y++;
}
else {
count++;
x--;
y++;
}
}
if (count > 0) {
return true;
}
return false;
}
}
【group anagrams】
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
//cc
if (strs == null || strs.length == 0) return new ArrayList<List<String>>();
//ini: map, char[]
Map<String, List<String>> map = new HashMap<>();
//for loop: add to char, to map
for (String str : strs) {
char[] chars = str.toCharArray();
//顺序统一以后都一样
Arrays.sort(chars);
String anagram = String.valueOf(chars);
//then add to map
if (!map.containsKey(anagram)) map.put(anagram, new ArrayList<String>());
map.get(anagram).add(str);
}
//return (map)
return new ArrayList<List<String>>(map.values());
}
}
【find second maximum】固定2个数
// JAVA Code for Find Second largest
// element in an array
class GFG {
/* Function to print the second largest
elements */
public static void print2largest(int arr[],
int arr_size)
{
int i, first, second;
/* There should be atleast two elements */
if (arr_size < 2)
{
System.out.print(" Invalid Input ");
return;
}
first = second = Integer.MIN_VALUE;
for (i = 0; i < arr_size ; i++)
{
/* If current element is smaller than
first then update both first and second */
if (arr[i] > first)
{
second = first;
first = arr[i];
}
/* If arr[i] is in between first and
second then update second */
else if (arr[i] > second && arr[i] != first)
second = arr[i];
}
if (second == Integer.MIN_VALUE)
System.out.print("There is no second largest"+
" element\n");
else
System.out.print("The second largest element"+
" is "+ second);
}
【Find All Duplicates in an Array】
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int size = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != nums[size]) {
//compare with the last number
nums[++size] = nums[i];
//注意是先加再给
}
}
return size + 1;
}
}
【difference】
比较基础 递归 迭代:本身、堆栈、基础条件
基本 函数体中的语句调用函数本身。 允许重复执行指令集。
格式 在递归函数中,仅指定终止条件(基本情况)。 迭代包括初始化,条件,循环内语句的执行以及控制变量的更新(递增和递减)。
终止 条件语句包含在函数体中,以强制函数返回而不执行递归调用。 重复执行迭代语句,直到达到某个条件。
条件 如果函数没有收敛到某个称为(基本情况)的条件,则会导致无限递归。 如果迭代语句中的控制条件永远不会变为false,则会导致无限次迭代。
无限重复 无限递归可能会导致系统崩溃。 无限循环重复使用CPU周期。
应用的 递归始终应用于函数。 迭代应用于迭代语句或“循环”。
堆 每次调用函数时,堆栈用于存储一组新的局部变量和参数。 不使用堆栈。
高架 递归拥有重复函数调用的开销。 没有重复函数调用的开销。
速度 执行缓慢。 快速执行。
代码大小 递归减少了代码的大小。 迭代使代码更长。
【】