1、乘积最大子数组
分析:因为有负数的存在,最大值随时可能变成最小值,最小值也随时可能变成最大值。
因此需要保存最小值,碰到负数的时候需要将最大值和最小值交换。
2、零钱兑换
3、根据身高重建队列
我愿称之为拐弯抹角第一名。
分析:首先根据身高进行排序,然后依次根据k值来确定插入的位置(假如k为0,说明该数对是当前的第一个数对,假如为3,说明该数对的前边应该有3个数对)
class Solution {
public int[][] reconstructQueue(int[][] people) {
if(people.length == 0 || people[0].length == 0){return new int[0][0];}
ArrayList<int[]> res = new ArrayList<>();
Arrays.sort(people,new Comparator<int[]>(){
//按照身高降序,K升序排序
@Override
public int compare(int[]o1,int[]o2){
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0];
}
});
// for(int i = 0;i < people.length;i++){
// for(int k = 0;k < 2;k++){
// res.add(k,people[i]);
// }
// }
for(int[] i : people){
//k为下i,存放数组i
res.add(i[1],i);
}
return res.toArray(new int[0][]);
}
}
4、字符串解码
class Solution {
public String decodeString(String s) {
Stack<String> stack=new Stack<String>();
for(int i=0;i<s.length();i++) {
if(s.charAt(i)==']') {
String string="";
while(!stack.peek().equals("[")) {
string=stack.pop()+string;
}
stack.pop();
String countString="";
while((!stack.isEmpty())&&(stack.peek().charAt(0)>='0'&&stack.peek().charAt(0)<='9')) {
countString=stack.pop()+countString;
}
int count=Integer.parseInt(countString);
String retString="";
for(int j=0;j<count;j++) {
retString=retString+string;
}
stack.push(retString);
}
else {
String str=""+s.charAt(i);
stack.push(str);
}
}
String aaa="";
while(!stack.isEmpty()) {
aaa=stack.pop()+aaa;
}
return aaa;
}
}
5、单调递增的数字
class Solution {
/**
* 思路:
* 从右向左扫描数字,若发现当前数字比其左边一位(较高位)小,
* 则把其左边一位数字减1,并将该位及其右边的所有位改成9
*/
public static int monotoneIncreasingDigits(int n) {
String s = String.valueOf(n);
int length = s.length();
char[] chars = s.toCharArray();
int flag = length;
for (int i = length - 1; i >= 1; i--) {
if (chars[i] < chars[i - 1]) {
flag = i;
chars[i - 1]--;
}
}
for (int i = flag; i < length; i++) {
chars[i] = '9';
}
return Integer.parseInt(new String(chars));
}
}
6、二叉树的完全性检验
判断是否是完全二叉树:假如有右孩子,那么必定有左孩子,并且只有最后一层可以不是满的。
方法一: 广度遍历二叉树,当出现 null 值时停止遍历,如果此时还有没有遍历到的结点,说明该树非完全二叉树。
方法二: 层序遍历(其实和广度优先差不多),设置一个停止标志,遇到空节点,停止标志为真,如果停止标志为真,再遍历遇到非空节点,则非完全二叉树。
方法三: 深度优先。判断树的size 是否 等于 最后一个节点的indexCode
//广度优先
class Solution {
public boolean isCompleteTree(TreeNode root) {
if(root == null){return true;}
LinkedList<TreeNode> q = new LinkedList<>();
q.add(root);
TreeNode node;
//删到队列前端是null
while((node = q.removeFirst())!=null){
q.add(node.left);
q.add(node.right);
}
//此时,假如是完全二叉树,那么队列里全是null
while(!q.isEmpty()){
//removeLast()是删最后进去的
if(q.removeLast() !=null){
return false;
}
}
return true;
}
}
//深度优先
class Solution {
int max;
int count;
public boolean isCompleteTree(TreeNode root) {
cal(root,1);
return max == count;
}
private void cal(TreeNode root,int index){
if(root == null) return;
if(index > max){
max = index;
}
count++;
cal(root.left,2*index);
cal(root.right,2*index+1);
}
}
7、汉明距离总和
8、字母异位词分组
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<String,ArrayList<String>> map = new HashMap<>();
for(String s:strs){
char[] ch = s.toCharArray();
Arrays.sort(ch);
String key = String.valueOf(ch);
if(!map.containsKey(key)){
map.put(key,new ArrayList<>());
}
map.get(key).add(s);
}
return new ArrayList(map.values());
}
}
9、从尾到头打印链表
这个题挺简单的,但是没有想过用递归实现,贴一个递归的解法。
class Solution {
ArrayList<Integer> tmp = new ArrayList<Integer>();
public int[] reversePrint(ListNode head) {
recur(head);
int[] res = new int[tmp.size()];
for(int i = 0; i < res.length; i++)
res[i] = tmp.get(i);
return res;
}
void recur(ListNode head) {
if(head == null) return;
recur(head.next);
tmp.add(head.val);
}
}
//遍历一遍得出大小,再从后往前填数组
class Solution {
public int[] reversePrint(ListNode head) {
int count = 0;
ListNode cur = head;
while(cur!=null){
count++;
cur = cur.next;
}
int[] res = new int[count];
cur = head;
for(int i = res.length-1;i>=0;i--){
res[i] = cur.val;
cur = cur.next;
}
return res;
}
}
10、实现队列
class CQueue {
LinkedList<Integer> A, B;
public CQueue() {
A = new LinkedList<Integer>();
B = new LinkedList<Integer>();
}
public void appendTail(int value) {
A.addLast(value);
}
public int deleteHead() {
if(!B.isEmpty()) return B.removeLast();
if(A.isEmpty()) return -1;
while(!A.isEmpty())
B.addLast(A.removeLast());
return B.removeLast();
}
}
11、2的幂
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
class Solution {
public boolean isPowerOfTwo(int n) {
if(n <= 0){return false;}
if(n == 1){return true;}
if(n % 2 !=0){return false;}
return isPowerOfTwo(n/2);
}
}
// 解释:2的幂次方在二进制下,只有1位是1,其余全是0。例如:8---00001000。
//负数的在计算机中二进制表示为补码(原码->正常二进制表示,原码按位取反(0-1,1-0),最后再+1。
//然后两者进行与操作,得到的肯定是原码中最后一个二进制的1。例如8&(-8)->00001000 & 11111000 得 00001000,即8
class Solution {
public boolean isPowerOfTwo(int n) {
return (n > 0) && (n & -n) == n;
}
}
12、4的幂
先判断是否是2的幂,然后根据出现的1是在奇数位还是偶数位
class Solution{
public boolean isPowerOfFour(int num){
return (num > 0) && ((num & -num) == num) && ((num & 0x55555555) == num);
}
}





553

被折叠的 条评论
为什么被折叠?



