算法是码农的基本功,也是各个大厂必考察的重点,让我们一起坚持写题吧。
遇事不决,可问春风,春风不语,即是本心。
我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦,慢慢来,会很快,向前走,别回头。
1、搜索旋转排序数组II
思路:直接一个for循环就解决了,没看懂这个题目想干什么,有点意思。
Java版:
class Solution {
public boolean search(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
if(target == nums[i]){
return true ;
}
}
return false ;
}
}
2、删除排序链表中的重复元素II
思路:用map记录一下元素个数,当前元素个数大于1则跳过,否则摘下来拼接成链表。
Java版:
/**
* 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 deleteDuplicates(ListNode head) {
Map<Integer, Integer> map = new HashMap<>() ;
ListNode cur = head ;
while(cur != null){
if(map.get(cur.val) != null){
map.put(cur.val, map.get(cur.val) + 1) ;
}else{
map.put(cur.val, 1) ;
}
cur = cur.next ;
}
ListNode res = new ListNode(-1) ;
ListNode ans = res ;
while(head != null){
if(map.get(head.val) == 1){
res.next = new ListNode(head.val) ;
res = res.next ;
}
head = head.next ;
}
return ans.next ;
}
}
3、删除链表中重复元素
思路:记录元素出现次数,超过一次则删除当前节点即可。
Java版:
/**
* 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 deleteDuplicates(ListNode head) {
Map<Integer, Integer> map = new HashMap<>() ;
ListNode ans = new ListNode(0);
ListNode res = ans ;
while(head != null){
if(map.get(head.val) == null){
map.put(head.val, 1);
ans.next = new ListNode(head.val) ;
ans = ans.next ;
}else{
head = head.next ;
}
}
return res.next ;
}
}
4、分割链表
思路:遍历原始链表,维护两个链表,第一个链接存储小于x节点,第二个链表存储大雨等于x节点。然后两个链表拼接在一起。
Java版:
/**
* 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 partition(ListNode head, int x) {
if(head == null || head.next == null){
return head ;
}
// 维护两个链表,小于x的放到第一个链表,大于等于x的放到第二个链表
ListNode smart = new ListNode(head.val);
ListNode left = smart;
ListNode big = new ListNode(head.val) ;
ListNode right = big;
while(head != null){
if(head.val<x){
smart.next = new ListNode(head.val);
smart = smart.next;
}else{
big.next = new ListNode(head.val);
big = big.next;
}
head = head.next;
}
smart.next = right.next;
return left.next;
}
}
5、合并两个有序数组
思路:
1.简单拼接后排序即可
Java版:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i=0; i<n; i++){
nums1[i+m] = nums2[i];
}
Arrays.sort(nums1);
}
}
6、子集II
思路:递归+回溯+标记
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> tmp = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
dfs(false,nums,0);
return ans;
}
public void dfs(boolean vis, int [] nums, int cur){
if(cur==nums.length){
ans.add(new ArrayList<>(tmp));
return;
}
dfs(false,nums,cur+1);
if(!vis && cur>0 && nums[cur]==nums[cur-1]){
return;
}
tmp.add(nums[cur]);
dfs(true,nums,cur+1);
tmp.remove(tmp.size()-1);
}
}