class Solution {
// 简单方法:replaceAll()
public String replaceSpace1(String s) {
if(s == null || s.length() == 0){
return s;
}
return s.replaceAll(" ", "%20");
}
// 常规方法:StringBuilder
public String replaceSpace2(String s) {
if(s == null || s.length() == 0){
return s;
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i
class Solution {
// 简单方法,额外内存
public String reverseLeftWords(String s, int n) {
if(s == null || s.length() <= n){
return s;
}
String s1 = s.substring(0, n);
String s2 = s.substring(n, s.length());
return s2+s1;
}
// 不使用额外内存方法 按n切开,各自翻转字符串,最后整体翻转一次
public String reverseLeftWords(String s, int n) {
if (s == null || s.length() == 0) {
return s;
}
char[] ss = s.toCharArray();
reserve(ss, 0, n-1);
reserve(ss, n, ss.length-1);
reserve(ss, 0, ss.length-1);
return new String(ss);
}
public void reserve(char[] s, int left, int right) {
while (left <= right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
通过有限状态机处理
class Solution {
public boolean isNumber(String s) {
if(s == null || s.length() == 0){
return false;
}
Map[] stage = {
new HashMap(){{put('k', 0); put('d',2); put('s', 1); put('t',3);}}, // 0
new HashMap(){{put('d', 2); put('t',3);}}, // 1
new HashMap(){{put('d', 2);put('t',9);put('e',5);put('k', 8);}}, // 2
new HashMap(){{put('d', 4);}}, // 3
new HashMap(){{put('d', 4);put('e',5);put('k', 8);}}, // 4
new HashMap(){{put('s', 6);put('d',7);}}, // 5
new HashMap(){{put('d', 7);}}, // 6
new HashMap(){{put('d', 7); put('k', 8);}}, // 7
new HashMap(){{put('k', 8);}}, // 8
new HashMap(){{put('k', 8);put('d', 4);put('e', 5);}} // 9
};
int p = 0;
for(int i=0; i='0'&&c<='9'){
return 'd';
}
if(c == '.'){
return 't';
}
if(c == ' '){
return 'k';
}
if(c == 'e' || c == 'E'){
return 'e';
}
if(c == '+' || c == '-'){
return 's';
}
return null;
}
}
整数 | 值 |
---|---|
最小值 | -2147483648 |
最大值 | 2147483647 |
public int strToInt(String str) {
if (str == null || str.length() == 0) {
return 0;
}
int i = 0;
int count = 0;
int flag = 1;
while (i < str.length() && str.charAt(i) == ' ') {
i++;
}
if (i < str.length() && (str.charAt(i) == '+' || str.charAt(i) == '-')) {
flag = str.charAt(i) == '+' ? 1 : -1;
i++;
}
while (i < str.length()) {
int tmp = str.charAt(i) - '0';
if (tmp < 0 || tmp > 9) {
return count*flag;
}
if (count < Integer.MAX_VALUE / 10 || (count == Integer.MAX_VALUE / 10 && tmp <= 7)) {
count = count * 10 + tmp;
}else{
return flag>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
}
i++;
}
return count*flag;
}
// split分割
public String reverseWords(String s) {
if(s==null ||s.length() == 0){
return s;
}
String[] words = s.split(" ");
StringBuffer sb = new StringBuffer();
for(int i = words.length-1; i>=0; i--){
if(!words[i].equals("")){
sb.append(words[i]);
sb.append(" ");
}
}
String result = sb.toString();
// 注意判断长度
return result.length()>0?result.substring(0, result.length()-1):"";
}
// 双指针反转,不去除空格,每个单词反转,再整体反转
public String reverseWords(String s) {
if (s == null || s.length() == 0) {
return s;
}
char[] chars = s.toCharArray();
int i = 0;
int j = 0;
while (i < chars.length) {
while (i < chars.length && chars[i] == ' ') {
i++;
j++;
}
while (j < chars.length && chars[j] != ' ') {
j++;
}
swap(chars, i, j-1);
i=j;
}
swap(chars, 0, chars.length-1);
return String.valueOf(chars);
}
// 普通哈希
class Solution {
public char firstUniqChar(String s) {
HashMap dic = new HashMap<>();
char[] sc = s.toCharArray();
for(char c : sc)
dic.put(c, !dic.containsKey(c));
for(char c : sc)
if(dic.get(c)) return c;
return ' ';
}
}
// 有序哈希LinedHashMap
class Solution {
public char firstUniqChar(String s) {
Map dic = new LinkedHashMap<>();
char[] sc = s.toCharArray();
for(char c : sc)
dic.put(c, !dic.containsKey(c));
for(Map.Entry d : dic.entrySet()){
if(d.getValue()) return d.getKey();
}
return ' ';
}
}
1.反转链表:用到中间node "next"
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
// 通过两个哈希表,内存占用多
public ListNode copyRandomList(ListNode head) {
if (head == null) {
return head;
}
Map old2new = Maps.newHashMap();
Map new2old = Maps.newHashMap();
ListNode newHead = genNewListNodeByOld(head, old2new, new2old);
ListNode cur = newHead;
while (head.next != null) {
cur.next = genNewListNodeByOld(head.next, old2new, new2old);
cur = cur.next;
head = head.next;
}
cur = newHead;
while (cur != null) {
cur.random = old2new.get(new2old.get(cur).random);
cur = cur.next;
}
return newHead;
}
public ListNode genNewListNodeByOld(ListNode oldNode, Map old2New,
Map new2Old) {
ListNode newNode = new ListNode(oldNode.val);
old2New.put(oldNode, newNode);
new2Old.put(newNode, oldNode);
return newNode;
}
// 通过链表重构加链表拆分
public ListNode copyRandomList(ListNode head) {
if (head == null) {
return head;
}
ListNode newHead = head;
while(head!=null){
ListNode newNode = new ListNode(head.val);
newNode.next = head.next;
head.next = newNode;
head = head.next.next;
}
head = newHead;
while(head!=null){
// 注意: 特别处理null!!!
head.next.random = head.random == null?null:head.random.next;
head = head.next.next;
}
head = newHead;
newHead = newHead.next;
while(head!=null){
ListNode newNode = head.next;
head.next = head.next.next;
// 注意: 特别处理null!!!
newNode.next = newNode.next == null?null:newNode.next.next;
head = head.next;
}
return newHead;
}
public ListNode deleteNode(ListNode head, int val) {
ListNode begin = head;
ListNode preview = null;
while (begin != null) {
if (begin.val == val) {
if (preview != null) { // 注意判空
preview.next = begin.next;
} else {
head = head.next;
}
}
preview = begin;
begin = begin.next;
}
return head;
}
// 通过arrayList获取
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null){
return null;
}
List nodes = new ArrayList<>();
while(head!=null){
nodes.add(head);
head = head.next;
}
if(nodes.size()0){
head = head.next;
k--;
}
if(head == null&&k>0){
return null;
}
while(head!=null){
latter = latter.next;
head = head.next;
}
return latter;
}
合并排序链表
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode begin = new ListNode(0);
ListNode p = begin;
while(l1!=null && l2!=null){
if(l1.val<=l2.val){
begin.next = l1;
l1 = l1.next;
}else{
begin.next = l2;
l2 = l2.next;
}
begin = begin.next;
}
while(l1!=null){
begin.next = l1;
l1 = l1.next;
begin = begin.next;
}
while(l2!=null){
begin.next = l2;
l2 = l2.next;
begin = begin.next;
}
return p.next;
}
// 直观方法,两个stack
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Stack a = new Stack<>();
Stack b = new Stack<>();
for(ListNode head = headA; head !=null; head = head.next){
a.push(head);
}
for(ListNode head = headB; head!=null; head = head.next){
b.push(head);
}
ListNode common = null;
while(a.size()>0 && b.size()>0 && a.peek() == b.peek()){
common = a.pop();
b.pop();
}
return common;
}
// 数学方法,双指针相遇
A走完到common, a+b-c
B走完到common, b+a-c
相等的的点就是重合的点
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA;
ListNode b = headB;
while(a!=b){
a = a == null?headB:a.next;
b = b == null?headA:b.next;
}
return a;
}
public int[] reversePrint(ListNode head) {
if(head == null){
return new int[0];
}
Stack stack = new Stack<>();
while(head!=null){
stack.push(head);
head = head.next;
}
int[] vals = new int[stack.size()];
for(int i = 0; i
class CQueue {
public static Stack stack1;
public static Stack stack2;
public CQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
if (stack2.size() == 0) {
while (stack1.size() > 0) {
stack2.push(stack1.pop());
}
}
return stack2.size() > 0 ? stack2.pop() : -1;
}
}
class MinStack {
Stack mainStack;
Stack minStack;
/**
* initialize your data structure here.
*/
public MinStack() {
mainStack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
mainStack.push(x);
if (minStack.empty() || x <= minStack.peek()) {
minStack.push(x);
}
}
public void pop() {
int x = mainStack.pop();
if (minStack.size() > 0 && minStack.peek() == x) {
minStack.pop();
}
}
public int top() {
return mainStack.peek();
}
public int min() {
return minStack.peek();
}
}
剑指 Offer 31. 栈的压入、弹出序列
public boolean validateStackSequences(int[] pushed, int[] popped) {
if(pushed == null || popped == null || pushed.length != popped.length){
return false;
}
Stack mockStack = new Stack<>();
int cursorP = 0;
for(int i = 0; i0 && cursorP
class MaxQueue {
LinkedList mainQueue;
LinkedList maxQueue;
public MaxQueue() {
mainQueue = new LinkedList();
maxQueue = new LinkedList();
}
public int max_value() {
if (maxQueue.size() == 0) {
return -1;
}
return maxQueue.peek();
}
public void push_back(int value) {
while (maxQueue.size() > 0 && mainQueue.getLast() < value) {
maxQueue.removeLast();
}
mainQueue.offer(value);
}
public int pop_front() {
int value = mainQueue.isEmpty() ? -1 : mainQueue.poll();
if (maxQueue.size() != 0 && mainQueue.peek() == value) {
maxQueue.poll();
}
return value;
}
public static void main(String args[]) {
MaxQueue maxQueue = new MaxQueue();
maxQueue.push_back(1);
maxQueue.push_back(2);
maxQueue.max_value();
maxQueue.pop_front();
maxQueue.max_value();
}
}
public int[] exchange(int[] nums) {
if (nums == null || nums.length <= 1) {
return nums;
}
int i = 0;
int j = nums.length - 1;
while (i < j) {
while (i < j && nums[i] % 2 == 1) {
i++;
}
while (i < j && nums[j] % 2 == 0) {
j--;
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
return nums;
}
public int[] twoSum(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return null;
}
int left = 0;
int right = nums.length - 1;
while (left < right) {
if (target == nums[left] + nums[right]) {
return new int[] {nums[left], nums[right]};
} else if (target < nums[left] + nums[right]) {
right--;
} else {
left++;
}
}
return null;
}
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return null;
}
List maxList = new ArrayList<>();
// 队列用于记录最后最大值
LinkedList q = new LinkedList<>();
// 用于记录最大值
Integer max = nums[0];
// 窗口未满不用移动
for (int i = 0; i < nums.length && i < k; i++) {
while (q.size() > 0 && nums[i] > q.getLast()) {
q.removeLast();
}
q.add(nums[i]);
max = max > nums[i] ? max : nums[i];
}
maxList.add(max);
// 窗口满了以后,每移动一步,判断窗口开始值前一个(i-k)是否为最大值,是则移除
for (int i = k; i < nums.length; i++) {
while (q.size() > 0 && nums[i] > q.getLast()) {
q.removeLast();
}
q.add(nums[i]);
max = max > nums[i] ? max : nums[i];
if (nums[i - k] == max) {
q.removeFirst();
max = q.getFirst();
}
maxList.add(max);
}
int a[] = new int[maxList.size()];
for (int i = 0; i < maxList.size(); i++) {
a[i] = maxList.get(i);
}
return a;
}
螺旋打印数组力扣
public int[] spiralOrder(int[][] matrix) {
if (matrix == null || matrix.length == 0) {
return new int[0];
}
int rowEnd = matrix.length - 1;
int colEnd = matrix[0].length - 1;
int rowBegin = 0;
int colBegin = 0;
int r = 0;
int c = 0;
int[] result = new int[matrix.length * matrix[0].length];
int cursor = 0;
while (rowBegin < rowEnd && colBegin < colEnd) {
while (c < colEnd) {
result[cursor++] = matrix[r][c++];
}
while (r < rowEnd) {
result[cursor++] = matrix[r++][c];
}
while (c > colBegin) {
result[cursor++] = matrix[r][c--];
}
while (r > rowBegin) {
result[cursor++] = matrix[r--][c];
}
rowBegin++;
rowEnd--;
colBegin++;
colEnd--;
r = rowBegin;
c = colBegin;
}
if (rowBegin == rowEnd) {
for (c = colBegin; c <= colEnd; c++) {
result[cursor++] = matrix[r][c];
}
} else if(colBegin == colEnd){
for (r = rowBegin; r <= rowEnd; r++) {
result[cursor++] = matrix[r][c];
}
}
return result;
}
数组的重复数字
力扣
// 通过哈希表
public int findRepeatNumber(int[] nums) {
if(nums == null || nums.length == 0){
return -1;
}
Set numSet = new HashSet<>();
for(int i = 0;i
剑指 Offer 53 - I. 在排序数组中查找数字 I
public static int search(int[] nums, int target) {
if(nums == null || nums.length == 0){
return 0;
}
// 查找右边界
int end = findBand(nums, target);
// 查找左边界
int begin = findBand(nums, target-1);
return end-begin;
}
public static int findBand(int nums[], int target){
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = (left+right)/2;
if(nums[mid]<=target){
left = mid+1;
}else {
right = mid-1;
}
}
return left;
}
剑指 Offer 53 - II. 0~n-1中缺失的数字 - 力扣(LeetCode)
public int missingNumber(int[] nums) {
if(nums == null || nums.length == 0){
return -1;
}
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = (left+right)/2;
if(nums[mid] == mid){
left = mid+1;
}else{
right = mid-1;
}
}
return left;
}
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0){
return false;
}
int i = matrix[0].length-1;
int j = 0;
while(i>=0 && jtarget){
i--;
}else if(matrix[j][i]
力扣
public int minArray(int[] numbers) {
if(numbers == null || numbers.length == 0){
return -1;
}
int left = 0;
int right = numbers.length-1;
while(leftnumbers[right]){
left = mid+1;
// 小于,可能为最小值或在左边
}else if(numbers[mid]
public int[] levelOrder(TreeNode root) {
if(root == null){
return new int[0];
}
List valList = new ArrayList<>();
Queue tmpQueue = new LinkedList<>();
tmpQueue.offer(root);
while(tmpQueue.size()>0){
TreeNode node = tmpQueue.poll();
valList.add(node.val);
if(node.left!=null){
tmpQueue.offer(node.left);
}
if(node.right!=null){
tmpQueue.offer(node.right);
}
}
int[] result = new int[valList.size()];
for(int i = 0; i
力扣
public List> levelOrder(TreeNode root) {
List> result = new ArrayList<>();
if(root==null){
return result;
}
Queue queue1 = new LinkedList<>();
Queue queue2 = new LinkedList<>();
queue1.offer(root);
List tmp = new ArrayList<>();
while(queue1.size()>0){
TreeNode curNode = queue1.poll();
tmp.add(curNode.val);
if(curNode.left!=null){
queue2.offer(curNode.left);
}
if(curNode.right!=null){
queue2.offer(curNode.right);
}
if(queue1.size() == 0){
result.add(tmp);
tmp = new ArrayList<>();
Queue tmpp = queue1;
queue1 = queue2;
queue2 = tmpp;
}
}
return result;
}
public List> levelOrder(TreeNode root) {
List> result = new ArrayList<>();
if(root == null){
return result;
}
// 注意此处申明,必须是LinkedList才有addFirst方法!!
LinkedList tmpResult = new LinkedList<>();
boolean flag = true;
Queue queue1 = new LinkedList<>();
Queue queue2 = new LinkedList<>();
queue1.offer(root);
while(queue1.size()>0){
// 之字形,在上一题的基础上,反正打印就行了,不用转换队列写入顺序!!
root = queue1.poll();
if(flag){
tmpResult.add(root.val);
}else{
tmpResult.addFirst(root.val);
}
if(root.left!=null){
queue2.offer(root.left);
}
if(root.right!=null){
queue2.offer(root.right);
}
if(queue1.size() == 0){
result.add(tmpResult);
tmpResult = new LinkedList<>();
queue1 = queue2;
queue2 = new LinkedList<>();
flag = !flag;
}
}
return result;
}
public boolean isSubStructure(TreeNode A, TreeNode B) {
// 由于约定空树不为子树,因此需为不等于null,三种可能:相同树,为右子树,为左子树
return (A!=null && B!=null &&(isSameTree(A, B)||isSubStructure(A.left, B)||isSubStructure(A.right, B)));
}
// 相同树,
public boolean isSameTree(TreeNode A, TreeNode B) {
// B为null,说明递归到头了,返回true
if(B == null){
return true;
}
// 否则,A为null,说明A cover不住B,返回false
if(A == null || A.val!=B.val){
return false;
}
// 循环判断左右节点
return isSameTree(A.left, B.left) && isSameTree(A.right, B.right);
}