目录
数组
2.二分查找
704.二分查找
c++
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int middle = (left + right)/2;
if(target > nums[middle]){
left = middle + 1;
}else if(target < nums[middle]){
right = middle - 1;
}else{
return middle;
}
}
return -1;
}
};
java
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = (left + right) / 2;
if(target > nums[mid]){
left = mid + 1;
}else if(target < nums[mid]){
right = mid -1;
}else{
return mid;
}
}
return -1;
}
}
35.搜索插入位置
c++
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int mid = (left + right) / 2;
if(target < nums[mid]){
right = mid - 1;
}else if(target > nums[mid]){
left = mid + 1;
}else{
return mid;
}
}
return right + 1;
}
};
34.在排序数组中查找元素的第一个和最后一个位置
c++
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int rightBorder = getRightBorder(nums, target);
int leftBorder = getLeftBorder(nums, target);
//
if(rightBorder == -2 || leftBorder == -2){
return {-1, -1};
}else if(rightBorder - leftBorder > 1){
return {leftBorder + 1, rightBorder - 1};
}else{
return {-1, -1};
}
}
private:
int getRightBorder(vector<int>& nums, int target){
int left = 0;
int right = nums.size() - 1;
int rightBorder = -2;
while(left <= right){
int mid = (left + right) / 2;
if(target < nums[mid]){
right = mid - 1;
}else{
left = mid + 1;
rightBorder = left;
}
}
return rightBorder;
}
int getLeftBorder(vector<int>& nums, int target){
int left = 0;
int right = nums.size() - 1;
int leftBorder = -2;
while(left <= right){
int mid = (left + right) / 2;
if(target <= nums[mid]){
right = mid - 1;
leftBorder = right;
}else{
left = mid + 1;
}
}
return leftBorder;
}
};
java
class Solution {
public int[] searchRange(int[] nums, int target) {
int rightBorder = getRightBorder(nums, target);
int leftBorder = getLeftBorder(nums, target);
if(rightBorder == -2 || leftBorder == -2){
return new int[]{-1, -1};
}else if(rightBorder - leftBorder > 1){
return new int[]{leftBorder + 1, rightBorder - 1};
}else{
return new int[]{-1 ,-1};
}
}
int getRightBorder(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
int rightBorder = -2;
while(left <= right){
int mid = (left + right)/2;
if(target < nums[mid]){
right = mid - 1;
}else{
left = mid + 1;
rightBorder = left;
}
}
return rightBorder;
}
int getLeftBorder(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
int leftBorder = -2;
while(left <= right){
int mid = (left + right)/2;
if(target >= nums[mid]){
left = mid + 1;
}else{
right = mid - 1;
leftBorder = right;
}
}
return leftBorder;
}
}
69.X的平方根
c++
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
int ans = -1;
while(left <= right){
int mid = (left + right)/2;
if((long long)mid * mid > x){
right = mid - 1;
}else{
left = mid + 1;
ans = mid;
}
}
return ans;
}
};
java
class Solution {
public int mySqrt(int x) {
int left = 0;
int right = x;
int ans = -1;
while(left <= right){
int mid = left + (right - left)/2;
if((long)mid * mid <= x)
{
ans = mid;
left = mid + 1;
}else{
right = mid - 1;
}
}
return ans;
}
}
367.有效的完全平方数
c++
class Solution {
public:
bool isPerfectSquare(int num) {
int left = 0;
int right = num;
int ans = -1;
while(left <= right){
int mid = left + (right - left)/2;
if((long long)mid * mid < num){
left = mid + 1;
}else if((long long)mid * mid > num){
right = mid - 1;
}else{
ans = mid;
break;
}
}
if(ans == -1){
return false;
}else{
return true;
}
}
};
java
class Solution {
public boolean isPerfectSquare(int num) {
int left = 0;
int right = num;
int ans = -1;
while(left <= right){
int mid = left + (right - left)/2;
if((long)mid * mid < num){
left = mid + 1;
}else if((long)mid * mid > num){
right = mid - 1;
}else{
ans = mid;
break;
}
}
if(ans == -1){
return false;
}else{
return true;
}
}
}
3.移除元素
27.移除元素
c++
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fastIndex = 0;
int lowIndex = 0;
for(fastIndex=0;fastIndex<nums.size();fastIndex++){
if(nums[fastIndex]!=val){
nums[lowIndex++] = nums[fastIndex];
}
}
return lowIndex;
}
};
java
class Solution {
public int removeElement(int[] nums, int val) {
int fastIndex = 0;
int lowIndex = 0;
for(fastIndex=0;fastIndex<nums.length;fastIndex++){
if(val!=nums[fastIndex]){
nums[lowIndex]=nums[fastIndex];
lowIndex++;
}
}
return lowIndex;
}
}
283.移动零
c++
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int fastIndex = 0;
int lowIndex = 0;
for(fastIndex = 0; fastIndex < nums.size(); fastIndex ++){
if(nums[fastIndex] != 0){
nums[lowIndex++] = nums[fastIndex];
}
}
for(;lowIndex < nums.size(); lowIndex ++){
nums[lowIndex] = 0;
}
}
};
java
class Solution {
public void moveZeroes(int[] nums) {
int lowIndex = 0;
for(int fastIndex = 0; fastIndex < nums.length; fastIndex ++){
if(nums[fastIndex] != 0){
nums[lowIndex] = nums[fastIndex];
lowIndex ++;
}
}
for(;lowIndex < nums.length; lowIndex ++){
nums[lowIndex] = 0;
}
}
}
844.比较含退格的字符串
c++
class Solution {
public:
bool backspaceCompare(string s, string t) {
int sIndex = 0;
int tIndex = 0;
int i = s.size() - 1;
int j = t.size() - 1;
while(1){
while(i >= 0){
if(s[i] == '#'){
sIndex ++;
}else{
if(sIndex >0) sIndex --;
else break;
}
i--;
}
while(j >= 0){
if(t[j] == '#'){
tIndex++;
}else{
if(tIndex > 0) tIndex--;
else break;
}
j--;
}
if(i < 0 || j < 0) break;
if(s[i] != t[j]) return false;
i--;j--;
}
if(i == -1 && j == -1) return true;
return false;
}
};
java :双指针
class Solution {
public boolean backspaceCompare(String S, String T) {
int sIndex = 0;
int tIndex = 0;
int i = S.length() - 1;
int j = T.length() - 1;
char[] s = S.toCharArray();
char[] t = T.toCharArray();
while(true){
while(i >= 0){
if(s[i] == '#'){
sIndex ++;
}else{
if(sIndex >0) sIndex --;
else break;
}
i--;
}
while(j >= 0){
if(t[j] == '#'){
tIndex++;
}else{
if(tIndex > 0) tIndex--;
else break;
}
j--;
}
if(i < 0 || j < 0) break;
if(s[i] != t[j]) return false;
i--;j--;
}
if(i == -1 && j == -1) return true;
return false;
}
}
java:栈
class Solution {
public boolean backspaceCompare(String S, String T) {
StringBuilder s = new StringBuilder();
StringBuilder t = new StringBuilder();
for(char c: S.toCharArray()){
if(c != '#'){
s.append(c);
}else if(s.length() > 0){
s.deleteCharAt(s.length() - 1);
}
}
for(char c: T.toCharArray()){
if(c != '#'){
t.append(c);
}else if(t.length() > 0){
t.deleteCharAt(t.length() - 1);
}
}
return s.toString().equals(t.toString());
}
}
4.有序数组的平方
97.有序数组的平方
c++
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int size = nums.size();
vector<int> ans(size,0);
int k = size - 1;
for(int i = 0,j = size - 1;i <= j;){
if(nums[i] * nums[i] < nums[j] * nums[j]){
ans[k] = nums[j] * nums[j];
j--;
}else{
ans[k] = nums[i] * nums[i];
i++;
}
k--;
}
return ans;
}
};
java
class Solution {
public int[] sortedSquares(int[] nums) {
int size = nums.length;
int[] ans = new int[size];
for(int i = 0,j = size -1, k = size -1;i <= j;k--){
if(nums[i] * nums[i] < nums[j] * nums[j]){
ans[k] = nums[j] * nums[j];
j--;
}else{
ans[k] = nums[i] * nums[i];
i++;
}
}
return ans;
}
}
5.长度最小的子数组
209.长度最小的子数组(滑窗)
c++
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int i = 0;
int sum = 0;
for(int j = 0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
int len = (j - i + 1);
result = result > len ? len:result;
sum -= nums[i++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
java
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int result = Integer.MAX_VALUE;
int i = 0;
int sum = 0;
for(int j = 0; j < nums.length; j++){
sum += nums[j];
while(sum >= target){
result = Math.min(result, j - i + 1);
sum -= nums[i++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
904.水果篮子(最大滑动窗口)
c++
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int n = fruits.size();
int left = 0;
int ans = 0;
unordered_map<int, int> cnt;
for(int right = 0; right < n; ++right){
++cnt[fruits[right]];
while(cnt.size() > 2){
auto it = cnt.find(fruits[left]);
--it->second;
if(it->second == 0){
cnt.erase(fruits[left]);
}
++left;
}
ans = max(ans, right - left + 1);
}
return ans;
}
};
java
class Solution {
public int totalFruit(int[] fruits) {
int n = fruits.length;
Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();
int left = 0, ans = 0;
for (int right = 0; right < n; ++right) {
cnt.put(fruits[right], cnt.getOrDefault(fruits[right], 0) + 1);
while (cnt.size() > 2) {
cnt.put(fruits[left], cnt.get(fruits[left]) - 1);
if (cnt.get(fruits[left]) == 0) {
cnt.remove(fruits[left]);
}
++left;
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}
6.螺旋矩阵2
59.螺旋矩阵
c++
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int startx = 0, starty = 0;
int offest = 1;
vector<vector<int>> array(n, vector<int>(n, 0));
int count = 1;
int i,j;
int mid = n/2;
while(mid --){
i = startx;
j = starty;
for(j = starty; j < n - offest; j++){
array[startx][j] = count++;
}
for(i = startx; i < n - offest; i++){
array[i][j] = count++;
}
for(; j > starty; j--){
array[i][j] = count++;
}
for(; i > startx; i--){
array[i][j] = count++;
}
startx ++;
starty ++;
offest ++;
}
if(n % 2){
array[n/2][n/2] = count;
}
return array;
}
};
java
class Solution {
public int[][] generateMatrix(int n) {
int startx = 0, starty = 0;
int[][] res = new int[n][n];
int offset = 1;
int mid = n/2;
int i,j;
int count = 1;
while(mid-- > 0){
i = startx;
j = starty;
for(j = starty; j < n - offset; j++){
res[startx][j] = count++;
}
for(i = startx; i < n - offset; i++){
res[i][j] = count++;
}
for(; j > starty; j--){
res[i][j] = count++;
}
for(; i > startx; i--){
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if(n % 2 != 0){
res[n/2][n/2] = count;
}
return res;
}
}
链表
链表初始化
运行helloworld.java
用力扣刷算法没有输入输出,以下是配置环境然后运行的博客
(28条消息) idea创建并运行第一个java程序_LYSnowy的博客-CSDN博客
2.移除链表元素
203.移除链表元素
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;//添加头结点
ListNode pre = dummy;
ListNode cur = head;
while(cur != null){
if(cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
3.设计链表
707.设计链表
理论考研的时候就会了,但是不一定会ac,链表定义很重要。
class ListNode{
int val;
ListNode next;
ListNode(){}
ListNode(int val){this.val = val;}
ListNode(int val, ListNode next){this.val = val; this.next = next;}
}
class MyLinkedList {
int size; //存储链表元素的个数
ListNode head; //虚拟头结点
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if(index < 0 || index >= size) return -1;
ListNode cur = head;
for(int i = 0; i <= index; i++){
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if(index > size) return ;
if(index < 0) index = 0;
size++;
ListNode pred = head;
for(int i = 0; i < index; i++){
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >= size)
return ;
size--;
if(index == 0)
{
head = head.next;
}else{
ListNode pred = head;
for(int i = 0; i < index; i++){
pred = pred.next;
}
pred.next = pred.next.next;
}
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
4.翻转链表
206.翻转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* } 双指针 ****************************************
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur != null){
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* } 递归 ***********************************
*/
class Solution {
public ListNode reverseList(ListNode cur, ListNode pre){
if(cur == null) return pre;
ListNode temp = cur.next;
cur.next = pre;
return reverseList(temp, cur);
}
public ListNode reverseList(ListNode head) {
return reverseList(head, null);
}
}
445.两数相加
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverse(ListNode l){
if(l == null) return l;
ListNode pre = null;
ListNode cur = l;
ListNode tmp = null;
while(cur != null){
tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int len1=0,len2=0;
ListNode cur1 = l1;
ListNode cur2 = l2;
//step1:求链表长度
while(cur1 != null){
len1++;
cur1 = cur1.next;
}
while(cur2 != null){
len2++;
cur2 = cur2.next;
}
//step2:翻转
l1 = reverse(l1);
l2 = reverse(l2);
//step3:相加
int add = 0,carry = 0;
if(len1<len2){
ListNode tmp = l1;
l1 = l2;
l2 = tmp;
}
cur1 = l1;
cur2 = l2;
//长度重合部分
while(cur1 != null && cur2 != null){
add = (cur1.val + cur2.val + carry);
if(add >= 10){//进位
carry = add / 10;
}else{
carry = 0;
}
cur1.val = add % 10;
cur1 = cur1.next;
cur2 = cur2.next;
}
//多出来的部分
while(cur1 != null && carry > 0){
add = cur1.val + carry;
if(add >= 10){//进位
carry = add / 10;
}else{
carry = 0;
}
cur1.val = add % 10;
cur1 = cur1.next;
}
//step4:翻转
l1 = reverse(l1);
//头插法,溢出
if(carry > 0){
ListNode addList = new ListNode(carry);
addList.next = l1;
l1 = addList;
}
return l1;
}
}
5.两两交换链表中的节点
24.两两交换链表中的节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode cur = dummy;
while(cur.next != null && cur.next.next != null){
ListNode temp = cur.next;
ListNode temp1 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp;
temp.next = temp1;
cur = cur.next.next;
}
return dummy.next;
}
}
6.删除链表的倒数第N个节点
19.删除链表的倒数第N个节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode fast = dummy;
ListNode slow = dummy;
while(n > 0){
fast = fast.next;
n--;
}
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
7. 链表相交
160.链表相交
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;
while(curA != null){
curA = curA.next;
lenA++;
}
while(curB != null){
curB = curB.next;
lenB++;
}
curA = headA;
curB = headB;
if(lenA > lenB){
int gap = lenA - lenB;
while(gap > 0){
curA = curA.next;
gap--;
}
}else{
int gap = lenB - lenA;
while(gap > 0){
curB = curB.next;
gap--;
}
}
while(curA != curB){
curA = curA.next;
curB = curB.next;
}
return curB;
}
}
8.环形链表
142.环形链表
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
ListNode index1 = head;
ListNode index2 = fast;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
哈希表
数组、hashset、hashmap
2.有效的字母异位词
242. 有效的字母异位词
class Solution {
public boolean isAnagram(String s, String t) {
int[] hash = new int[26];
for(int i = 0;i < s.length() ; i++){
hash[s.charAt(i) - 'a']++;
}
for(int i = 0; i < t.length() ; i++){
hash[t.charAt(i) - 'a']--;
}
for(int i = 0; i < 26; i++){
if(hash[i] != 0){
return false;
}
}
return true;
}
}
3.两个数的交集
hashset
import java.util.HashSet; //引入HashSet类
HashSet<String> a = new HashSet<String>(); //新建实例
a.add(1); //添加元素
a.contains(1); //判断元素是否存在于集合当中
a.remove(1); //删除集合中的元素
a.clear(); //删除所有元素
a.size(); //计算元素数量
//迭代
for(int i : a){
System.out.println(i);
}
349.两个数的交集
import java.util.HashSet;
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> result = new HashSet<Integer>();
HashSet<Integer> hash = new HashSet<Integer>();
for(int i : nums1){
if(!hash.contains(i)){
hash.add(i);
}
}
for(int i : nums2){
if(hash.contains(i)){
result.add(i);
}
}
int[] res = new int[result.size()];
int j = 0;
for(int i : result){
res[j++] = i;
}
return res;
}
}
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
4.快乐数
202.快乐数
import java.util.HashSet;
class Solution {
int SUM(int n){
int sum = 0;
while(n > 0){
sum += (n % 10)*(n % 10);
n /= 10;
}
return sum;
}
public boolean isHappy(int n) {
HashSet<Integer> hash = new HashSet<Integer>();
int sum = 0;
while(true){
if(n == 1) return true;
sum = SUM(n);
if(hash.contains(sum)){
return false;
}else{
hash.add(sum);
n = sum;
}
}
}
}
5.两数之和
hashmap
import java.util.HashMap; //引入HashMap类
HashMap<Integer, String> a = new HashMap<Integer, String>();
a.put(1,'a'); //添加
a.get(1); //获取key对应的value
a.remove(1); //删除
a.clear(); //删除所有
a.size(); //计算大小
//迭代
for(int i : a.keySet()){
System.out.println(i + a.get(i));
}
for(int i : a.values()){
System.out.println(i);
}
//方法
clone() //复制
isEmpty() // 判断是否为空
putAll() //将所有键/值对添加到 hashMap 中
putIfAbsent() //将所有键/值对添加到 hashMap 中
containsKey() //检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue() //检查 hashMap 中是否存在指定的 key 对应的映射关系。
replace() //检查 hashMap 中是否存在指定的 key 对应的映射关系。
replaceAll() //将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
getOrDefault() //获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach() //获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
entrySet() //返回 hashMap 中所有映射项的集合集合视图
merge() //返回 hashMap 中所有映射项的集合集合视图
compute() //返回 hashMap 中所有映射项的集合集合视图
computeIfAbsent() //返回 hashMap 中所有映射项的集合集合视图
computeIfPresent() //返回 hashMap 中所有映射项的集合集合视图
1.两数之和
import java.util.HashMap;
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
int[] result = new int[2];
for(int i = 0; i < nums.length; i++){
if(hash.isEmpty()){
hash.put(nums[i], i);
}else{
if(hash.containsKey(target - nums[i])){
result[1] = i;
result[0] = hash.get(target - nums[i]);
break;
}else{
hash.put(nums[i], i);
}
}
}
return result;
}
}
7.赎金信
383.赎金信
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] hash = new int[26];
for(int i = 0; i < magazine.length(); i++){
hash[magazine.charAt(i) - 'a']++;
}
for(int i = 0; i < ransomNote.length(); i++){
hash[ransomNote.charAt(i) - 'a']--;
}
for(int i = 0; i < 26; i++){
if(hash[i] < 0){
return false;
}
}
return true;
}
}
6.四数相加
454. 四数相加2
import java.util.HashMap;
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer, Integer> AB = new HashMap<Integer, Integer>();
int sum = 0;
for(int i : nums1){
for(int j : nums2){
sum = i + j;
AB.put(sum, AB.getOrDefault(sum, 0) + 1);
}
}
int count = 0;
for(int i : nums3){
for(int j : nums4){
sum = (i + j) * (-1);
count += AB.getOrDefault(sum, 0);
}
}
return count;
}
}
8.三数之和
ArrayList
import java.util.ArrayList;
ArrayList<E> a = new ArrayList<>();
a.add(1);
a.get(0);
a.set(0,2); //修改
a.remove(0);
a.size();
//迭代
for(int i = 0; i < a.size(); i++){
System.out.println(a.get(i));
}
a.sort();
a.indexOf(); //返回索引值
a.subList(); // 截取元素
a.toArray();
a.toString();
15.三数之和
import java.util.Arrays;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int i=0; i<nums.length; i++){
if(nums[i] > 0) return res;
if(i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1,right = nums.length -1 ;
while(right > left){
int sum = nums[i] + nums[left] + nums[right];
if(sum >0){
right--;
}else if(sum < 0){
left++;
}else{
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
//去重
while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
return res;
}
}
9.4数之和
4数之和
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int i = 0; i < nums.length; i++){
//剪枝
if(nums[i] > 0 && nums[i] > target) return res;
//去重
if(i > 0 && nums[i - 1] == nums[i]) continue;
for(int j = i + 1; j < nums.length; j++){
//去重
if(j > i + 1 && nums[j - 1] == nums[j]) continue;
int left = j + 1;
int right = nums.length - 1;
while(right > left){
long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
if(sum > target) right--;
else if(sum < target) left++;
else{
res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1]) left++;
left++;
right--;
}
}
}
}
return res;
}
}
字符串
1.翻转字符串
344.翻转字符串
class Solution {
public void reverseString(char[] s) {
char temp;
int right = s.length - 1;
int left = 0;
while(left < right){
temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
2.翻转字符串
541.翻转字符串
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0; i < ch.length; i += 2 * k){
int start = i;
int end = Math.min(ch.length - 1, start + k - 1);
while(start < end){
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
return new String(ch);
}
}
3.替换空格
05.替换空格
class Solution {
public String replaceSpace(String s) {
if(s.isEmpty()) return "";
StringBuffer sb = new StringBuffer();
for(int i = 0; i < s.length(); i++){
if(s.charAt(i)== ' '){
sb.append("%20");
}else{
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}
4.翻转字符串里的单词
151.翻转字符串里的单词
class Solution {
private StringBuilder removeSpace(String s){
int start = 0;
int end = s.length() - 1;
while(s.charAt(start) == ' ') start++;
while(s.charAt(end) == ' ') end--;
StringBuilder sb = new StringBuilder();
while(start <= end){
char c = s.charAt(start);
if(c != ' ' || sb.charAt(sb.length() - 1) != ' ')
sb.append(c);
start++;
}
return sb;
}
public void reverseString(StringBuilder sb, int start, int end){
while(start < end){
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
public void reverseEachWord(StringBuilder sb){
int start = 0;
int end = 1;
int n = sb.length();
while(start < n){
while(end < n && sb.charAt(end) != ' '){
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
public String reverseWords(String s) {
//移除多余空格
StringBuilder sb = removeSpace(s);
//将整个字符串反转
reverseString(sb, 0 , sb.length() - 1);
//将每个单词反转
reverseEachWord(sb);
return sb.toString();
}
}
5.左旋转字符串
58.左旋转字符串
//1、另开一个存储空间
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder(s);
StringBuilder res = new StringBuilder();
for(int i = n; i < sb.length(); i++){
res.append(sb.charAt(i));
}
for(int i = 0; i < n; i++){
res.append(sb.charAt(i));
}
return res.toString();
}
}
//2、使用一个存储空间
class Solution {
public void reverse(StringBuilder sb, int start, int end){
while(start < end){
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
public String reverseLeftWords(String s, int n) {
int len = s.length();
StringBuilder sb = new StringBuilder(s);
reverse(sb , 0 , n - 1);
reverse(sb , n , len - 1);
reverse(sb , 0 , len - 1);
return sb.toString();
}
}
6.实现strStr()
28.实现strStr()
class Solution {
private void getNext(int[] next, String s){
int j = 0;
next[0] = 0;
for(int i = 1; i < s.length(); i++){
while(j > 0 && s.charAt(j) != s.charAt(i))
j = next[j - 1];
if(s.charAt(j) == s.charAt(i)) j++;
next[i] = j;
}
}
public int strStr(String haystack, String needle) {
if(needle.length() == 0) return 0;
int[] next = new int[needle.length()];
getNext(next, needle);
int j = 0;
for(int i = 0; i < haystack.length(); i++){
while(j > 0 && needle.charAt(j) != haystack.charAt(i))
j = next[j - 1];
if(needle.charAt(j) == haystack.charAt(i))
j++;
if(j == needle.length())
return i - needle.length() + 1;
}
return -1;
}
}
双指针
1.移除元素
26.删除有序数组中的重复项
class Solution {
public int removeDuplicates(int[] nums) {
int slow=0;
for(int fast=0;fast<nums.length;fast++){
if(fast!=0 && nums[fast]==nums[fast-1]){
slow--;
}
nums[slow++]=nums[fast];
}
return slow;
}
}