class Solution {
public int singleNumber(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++)
result ^= nums[i];
return result;
}
}
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
//链表lli存放题目要求的元素
LinkedList<List<Integer>> lli = new LinkedList<>();
//注意:不能return null
if (root == null) return lli;
//队列queue用来遍历树
Queue<TreeNode> queue = new LinkedList<>();
//数组valarr用来存放每层元素
List<Integer> valarr = new ArrayList();
//结点ptr存放出队结点
TreeNode ptr;
//lvllen存放每层的结点总数,count存放该层已经出队列的结点数
int lvllen = 1, count = 0;
queue.add(root);
while (!queue.isEmpty()) {
//出队
ptr = queue.poll();
count++;
valarr.add(ptr.val);
if (ptr.left != null)
queue.add(ptr.left);
if (ptr.right != null)
queue.add(ptr.right);
//每层最后一个结点出队列后,重新set
if(count == lvllen) {
lli.addFirst(valarr);
//⑥由于上文已经定义了valarr的类型,此处重新申请内存时不需要再声明类型
valarr = new ArrayList();
count = 0;
lvllen = queue.size();
}
}
return lli;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public TreeNode sort
class Solution {
//思路:由于题意是高度平衡二叉树,且输入数组nums是递增数列,所以正中间是root
//左右两边分别是左右子树。题意又说,一个序列可以是某个平衡二叉树,所以我们
//可以将一个序列转化成左右子树结点个数相差1个的树,即左右子序列个数相差1个
//所以m = l + (r-l)/2 可以用来解决问题。由于/运算是向下取的,所以(r-l)/2表示正中间或偏左
public TreeNode sortedArrayToBST(int[] nums) {
return nums == null ? null : buildTree(nums, 0, nums.length-1);
}
public TreeNode buildTree(int[] nums, int l, int r) {
if (l > r) return null;
TreeNode root = new TreeNode();
//由于/运算是向下取的,所以(r-l)/2表示正中间或偏左
int m = l + (r-l)/2;
root.val = nums[m];
root.left = buildTree(nums, l, m-1);
root.right = buildTree(nums, m+1, r);
return root;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
int leftheight = getTreeHeight(root.left);
int rightheight = getTreeHeight(root.right);
if (leftheight == -1 || rightheight == -1)
return false;
return Math.abs(leftheight - rightheight) > 1 ? false : true;
}
public int getTreeHeight(TreeNode root) {
if (root == null) return 0;
int leftheight = getTreeHeight(root.left);
int rightheight = getTreeHeight(root.right);
//如果子树开始不平衡
if (Math.abs(leftheight - rightheight) > 1) return -1;
//如果某个结点的孩子已经是不平衡树,一直往上传递,该边的子树不平衡
if (leftheight == -1 || rightheight == -1) return -1;
return 1 + Math.max(leftheight,rightheight);
}
}
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
int leftheight = minDepth(root.left);
int rightheight = minDepth(root.right);
//只有右子树
if (leftheight == 0 && rightheight != 0)
return 1 + rightheight;
//只有左子树
else if (rightheight == 0 && leftheight != 0)
return 1 + leftheight;
//均有左右子树或者均无左右子树
else
return 1 + Math.min(leftheight, rightheight);
}
}
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
//思路:递归解决是否存在路径问题:递归传递剩余差
//如果当前结点是叶子结点,且结点值等于剩余差,即说明有路径
//如果存在路径,即指针传递到空节点,且空节点的父亲是叶子结点
if(root == null) return false;
boolean leftflag = false, rightflag = false;
int temp = sum-root.val;
//我们不能仅仅用一个hasPathSum(root, sum)函数来实现递归,
//1)最大根节点为null与子树为null不同。若测试用例为root = null, sum = 0,返回的应该是false;
//2)一定要判断是从根节点到叶子结点,而不能是“存在子路径”。若到了null子结点,且sum=0,但其父结点不是子结点,仍应返回false
//如果左子树有路径
leftflag = hasSubPathSum(root, root.left, sum-root.val);
//如果右子树有路径
rightflag = hasSubPathSum(root, root.right, sum-root.val);
//如果左子树有路径或者右子树有路径,说明该树有路径
return leftflag || rightflag;
}
public static boolean hasSubPathSum(TreeNode parent, TreeNode root, int sum) {
if (root == null) {
if(sum == 0 && parent != null && parent.left == null && parent.right == null)
return true;
else
return false;
}
boolean leftflag = false, rightflag = false;
leftflag = hasSubPathSum(root, root.left, sum-root.val);
rightflag = hasSubPathSum(root, root.right, sum-root.val);
return leftflag || rightflag;
}
}
方法二:
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null) return false;
if (root.val == sum) {
if (root.left == null && root.right == null)
return true;
}
boolean leftflag = false, rightflag = false;
leftflag = hasPathSum(root.left, sum-root.val);
rightflag = hasPathSum(root.right, sum-root.val);
return leftflag || rightflag;
}
}
class Solution {
public List<List<Integer>> generate(int numRows) {
LinkedList<List<Integer>> lld = new LinkedList<List<Integer>>();
if(numRows == 0) return lld;
List<Integer> l1 = new ArrayList<>();
l1.add(1);
lld.addLast(l1);
if (numRows == 1) return lld;
List<Integer> l2 = new ArrayList<>();
l2.add(1);
l2.add(1);
lld.addLast(l2);
if (numRows == 2) return lld;
LinkedList<Integer> movarr = new LinkedList<>();
movarr.add(1);
movarr.add(1);
for (int circnt = 2; circnt < numRows; circnt++)
generateYang(lld, movarr);
return lld;
}
public static void generateYang (LinkedList<List<Integer>> lld, LinkedList<Integer> movarr) {
LinkedList<Integer> lvl = new LinkedList<>();
lvl.add(1);
for(int i=0, j = 1; j < movarr.size(); i++, j++) {
int temp = movarr.get(i) + movarr.get(j);
lvl.add(temp);
}
lvl.add(1);
lld.add(lvl);
//movarr前半部分重新赋值
for (int i = 0; i < movarr.size(); i++)
movarr.set(i,lvl.get(i));
//movarr后半部分添加
for (int i = movarr.size(); i < lvl.size();i++)
movarr.add(lvl.get(i));
}
}
方法二:
//杨辉三角的性质:①第i行的元素个数为i个;②第i行两端元素为1,中间元素是第i-1行元素的和
//①Java中可扩展数组列表ArrayList(), 不会产生累赘元素;不可扩展数组int[]
//②拷贝ArrayList需要两个参数 pre = Arrays.copyOf(cur,j+1);一个是拷贝对象,一个是拷贝长度
class Solution {
public List<List<Integer>> generate(int numRows) {
//杨辉三角的性质:①第i行的元素个数为i个;②第i行两端元素为1,中间元素是第i-1行元素的和
List<List<Integer>> list = new ArrayList<>();
int[] pre = new int[numRows], cur = new int[numRows];
for (int j = 1; j <= numRows; j ++) {
//①Java中可扩展数组列表ArrayList(), 不会产生累赘元素;不可扩展数组int[]
List<Integer> subList = new ArrayList<Integer>();
for (int i = 0; i < j; i++) {
//两端元素为1
if (i == 0 || i == j)
cur[i] = 1;
else
cur[i] = pre[i-1] + pre[i];
//由于sublist是可扩展的数组,不会产生累赘元素
subList.add(cur[i]);
}
list.add(subList);
pre = Arrays.copyOf(cur,j+1);
}
return list;
}
}
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0 || prices.length == 1)
return 0;
int maxprofit = 0;
for (int i = 0; i < prices.length-1; i++) {
if (prices[i+1] > prices[i])
maxprofit += prices[i+1] - prices[i];
}
return maxprofit;
}
}
class MinStack {
public static Stack stack;
/** 构造器 */
public MinStack() {
stack = new Stack<Integer>();
}
public void push(int x) {
if (stack.empty()) {
stack.add(x);
stack.add(x);
}
else {
int topelement = stack.peek();
//int topelement = stack.peek();
//将最新元素压入栈
stack.add(x);
//当前栈内的最小元素压入栈
if (x > topelement)
stack.add(topelement);
else
stack.add(x);
}
}
public void pop() {
stack.pop();
stack.pop();
}
public int top() {
return stack.get(stack.size()-2);
}
public int getMin() {
return stack.get(stack.size()-1);
}
}
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode atr = headA, btr = headB;
int lenA = 0, lenB = 0;
while (atr != null) {
atr = atr.next;
lenA++;
}
atr = headB;
while (btr != null) {
btr = btr.next;
lenB++;
}
btr = headA;
//走同样的步数
if (lenA > lenB)
for (int i = 0 ; i < lenA - lenB; i++)
btr = btr.next;
else
for (int i = 0 ; i < lenB - lenA; i++)
atr = atr.next;
while (atr != null) {
if (atr == btr)
return atr;
else {
atr = atr.next;
btr = btr.next;
}
}
return null;
}
}
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] res = new int[2];
int left = 0, right = numbers.length-1;
while (left < right) {
if (numbers[left] + numbers[right] == target) {
res[0] = left+1;
res[1] = right+1;
}
//两数之和过大,则要缩小,故右游标左行
if (numbers[left] + numbers[right] > target)
right--;
//两数之和过小,则要放大,故左游标右行
else
left++;
}
return res;
}
}
class Solution {
public String convertToTitle(int n) {
StringBuilder sb = new StringBuilder();
while(n > 0) {
n--;
sb.append((char)(n%26 + 'A'));
n /= 26;
}
String result = sb.reverse().toString();
return result;
}
}
public void QuickSort(int[] nums, int left, int right) {
if (left >= right) return;
int pivot = nums[left], temp;
int ltr = left, rtr = right;
while (ltr < rtr) {
//rtr一直往左走,直到所指元素值小于pivot值;跳出循环时,rtr调到ltr上
while (nums[rtr] > pivot && ltr < rtr)
rtr--;
//ltr一直往右走,直到所指元素值大于pivot值
while (nums[ltr] < pivot && ltr < rtr)
ltr++;
//如果循环并未结束
if (ltr < rtr) {
temp = nums[rtr];
nums[rtr] = nums[ltr];
nums[ltr] = temp;
}
}
//跳出循环时,[left+1, ltr]均为小于pivot值,[rtr+1,right]均为大于pivot的值
nums[left] = nums[rtr];
nums[rtr] = pivot;
QuickSort(nums, left, rtr-1);
QuickSort(nums, rtr+1, right);
}
QuickSort(nums, 0, nums.length-1);
//或者使用Java现成的排序api
//Arrays.sort(nums);
//return nums[nums.length / 2];
int count = 1, curmeta = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] == curmeta) {
count++;
if (count > (nums.length/2))
return curmeta;
}
else {
curmeta = nums[i];
count = 1;
}
}
return nums[0];
方法二:哈希表
//Java HashMap类的常用使用
//1)声明变量类型:HashMap
//2)添加映射元素(1个映射元素叫entry):HashMap.put(K,V)
//3)判断是否存在某个哈希映射元素:HashMap.containsKey(K)
//4)根据V获取K:HashMap.getKey(V)
//5)根据K获取V:HashMap.getValue(K)
//6)遍历哈希表:用for-each方法
//for(Map.Entry
class Solution {
public int majorityElement(int[] nums) {
HashMap<Integer,Integer> hash = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (!hash.containsKey(nums[i] ))
hash.put(nums[i],1);
else{
int count = hash.get(nums[i]);
hash.put(nums[i],count+1);
}
}
for (Map.Entry<Integer,Integer> entry : hash.entrySet()) {
if (entry.getValue() > (nums.length / 2))
return entry.getKey();
}
return -1;
}
}
首先题目的意思是末尾有几个0
比如6! = 【1* 2* 3* 4* 5* 6】
其中只有25末尾才有0,所以就可以抛去其他数据 专门看2 5 以及其倍数 毕竟 4 * 25末尾也是0
比如10! = 【2456810】
其中 4能拆成22 10能拆成25
所以10! = 【2*(22)5(23)(222)(25)】
一个2和一个5配对 就产生一个0 所以10!末尾2个0
转头一想 2肯定比5多 所以只数5的个数就行了
假若N=31 31里能凑10的5为[5, 25, 35, 45, 25, 6*5] 其中 25还能拆为 52
所以 里面的5的个数为 int(31/(51)) + int(31/(52))
所以 只要先找个一个 5x < n 的x的最大数 然后按上面循环加起来
class Solution {
public int trailingZeroes(int n) {
int maxmi = 1, cntOfZeroes = 0;
while(Math.pow(5,maxmi) <= n)
maxmi++;
maxmi--;
for (int i = 1; i <= maxmi; i++)
cntOfZeroes += n / Math.pow(5,i);
return cntOfZeroes;
}
}
方法二:(妙) 重做!!!
1)将所有数组逆转
2)将前面k个元素逆转
3)将后面n-k个元素逆转
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
if (k > 0) {
inverseNumsArray(nums, 0, nums.length-1);
inverseNumsArray(nums, 0, k-1);
inverseNumsArray(nums, k, nums.length-1);
}
}
public void inverseNumsArray(int[] nums, int start, int end) {
int temp;
for (int i = start, j = end ; i < j ; i++, j--) {
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}