[leetcode top100] 0923 多数元素,反转链表,翻转二叉树,回文链表,移动零

这篇博客详细介绍了LeetCode中涉及的几种算法问题,包括多数元素的求解,链表的反转以及二叉树的翻转。对于多数元素,提供了使用哈希表和collections.Counter的方法;链表反转通过双指针迭代和递归两种方式实现;翻转二叉树则展示了递归和广度优先遍历的解决方案。这些算法都涉及到数据结构和高效操作。
摘要由CSDN通过智能技术生成

目录

169. 多数元素 - 力扣(LeetCode)

206. 反转链表 - 力扣(LeetCode)

226. 翻转二叉树 - 力扣(LeetCode)

234. 回文链表 - 力扣(LeetCode)

283. 移动零 - 力扣(LeetCode)



给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

思路:

在python中可以使用collection模块进行计数,collections.Counter().most_common(),返回的是dict(),key 是num,value是出现的次数。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        # python 还可以使用特有collection模块去计数
        count = collections.Counter(nums).most_common()
        return count[0][0]

可以使用哈希表,将num和出现的次数存储,最后找到出现次数大于n/2的元素。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        count = dict()
        for num in nums:
            count[num] = count.get(num,0) + 1    # 这一行重要
            if count[num] > len(nums) / 2:
                return num         

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n = nums.size();
        unordered_map<int,int> count;
        int key = 0,value = 0;
        for (auto& num:nums){
            count[num]++;
            if (count[num] > value){
                value = count[num];
                key = num;
            }
        }
        return key;     

    }
};

206. 反转链表 - 力扣(LeetCode)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

 

思路:

双指针迭代。

画图的方式可以很好理解,定义指针 pre=None,cur = head, tmp = head.next ,遍历整个链表,节点两两反转。

(python  and  c++)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        # 双指针迭代
        if not head or not head.next: return head
        pre,cur = None,head
        while cur:
            # tmp = cur.next
            # cur.next = pre
            # pre = cur
            # cur = tmp
            cur.next,pre,cur = pre,cur,cur.next
        return pre
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        //双指针  
        if (head == nullptr || head->next == nullptr) return head;
        ListNode* pre = nullptr,*cur = head;
        while (cur){
            ListNode* tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

递归。可以把迭代改成递归,这样空间复杂度会增加,但是代码更加简洁。通过递归公式让指针走到链表的导数第二个节点,之后进行翻转。(python and c++)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        # 递归
        if not head or not head.next:return head
        tmp = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return tmp
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        //递归
        if (head == nullptr || head->next == nullptr) return head;
        ListNode* tmp = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return tmp;
    }
};

226. 翻转二叉树 - 力扣(LeetCode)

思路:

关于树的问题,第一个应该想到的应该是递归,使用递归的方式找到左右子树叶节点,之后交换。 这里的递归,就是使用的DFS。(c++ and python)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        // 递归
        if (!root) return root;
        TreeNode* left = invertTree(root->left);
        TreeNode* right = invertTree(root->right);
        root->right = left;
        root->left = right;
        //swap(root->left,root->right);
        return root;
    }
};
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        # DFS
        if not root:return root
        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left = right
        root.right = left
        return root
  

BFS。广度优先遍历,每一次把每一层的节点放到队列中,依次拿出,将它的左右节点交换,之后将它的左右节点放入队列中。

(python and c++)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        # BFS
        if not root:return root
        que = [root]
        while que:
            tmp = que.pop()
            tmp.left,tmp.right = tmp.right,tmp.left
            if tmp.left:que.append(tmp.left)
            if tmp.right:que.append(tmp.right)
        return root 
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        // BFS
        if (root == nullptr) return root;
        queue<TreeNode*> que;
        que.push(root);
        while (!que.empty()){
            TreeNode* cur = que.front();
            que.pop();
            swap(cur->left,cur->right);
            if (cur->left) que.push(cur->left);
            if (cur->right) que.push(cur->right);
            
        }
        return root;
    }
};

234. 回文链表 - 力扣(LeetCode)

 

思路1:将链表的节点按照顺序放入到列表中,然后使用双指针遍历。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        # 列表+双指针
        seen = []
        while head:
            seen.append(head.val)
            head = head.next
        n = len(seen)
        left,right = 0,n-1
        while left < right:
            if seen[left] != seen[right]:
                return False
            left += 1
            right -= 1
        return True
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        //列表+双指针
        vector<int> seen;
        while (head){
            seen.push_back(head->val);
            head = head->next;
        }
        int n = seen.size();
        int left = 0,right = n-1;
        while (left < right){
            if (seen[left] != seen[right]) return false;
            left++;
            right--;
        }
        return true;
    }
};

思路2:使用快慢指针找到中间节点,之后翻转半部分链表,最后双指针遍历。

(python and  c++)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        # 列表+双指针
        pre = head
        cur = self.cutList(head)
        curReverse = self.reverseList(cur)
        #判断是否相同
        flag = True
        while flag and curReverse:
            if pre.val != curReverse.val:flag = False
            curReverse = curReverse.next
            pre = pre.next
        
        # 链表复原
        cur.next = self.reverseList(curReverse)
        return flag

    def cutList(self,head):
        # 找到中间节点
        left,right = head,head
        while right and right.next:
            left = left.next;
            right = right.next.next
        return left
    def reverseList(self,head):
        # 翻转后半部分链表
        if not head or not head.next: return head
        tmp = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return tmp
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
private:
    ListNode* cutList(ListNode* head){
        if (head == nullptr && head->next == nullptr) return head;
        ListNode* fast = head,*slow = head;
        while (fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }

    ListNode* reverseList(ListNode* head){
        if (!head || !head->next) return head;
        ListNode* tmp = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return tmp;
    }

public:
    bool isPalindrome(ListNode* head) {
        //双指针
        ListNode* pre = head;
        ListNode* cur = cutList(head);
        ListNode* curReverse = reverseList(cur);
        bool flag = true;
        while (flag && curReverse){
            if (pre->val != curReverse->val) flag = false;
            pre = pre->next;
            curReverse = curReverse->next;
        }
        // cur->next = reverseList(curReverse);
        return flag;

    }
};

283. 移动零 - 力扣(LeetCode)

 

思路:使用双指针,将数组中的0元素向后移动。左右指针均指向nums[0],若nums[right] != 0,交换nums[left] 和nums[right]。(python and  c++)

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        //使用双指针
        int left = 0,right = 0;
        int n = nums.size();
        while (right < n){
            if (nums[right] != 0){
                int tmp = nums[right];
                nums[right] = nums[left];
                nums[left] = tmp;
                left++;
            }
            right++;
        }
    }
};
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 双指针解法
        left,right = 0,0
        n = len(nums)
        while right < n:
            if nums[right] != 0:
                nums[left],nums[right] = nums[right],nums[left]
                left += 1
            right += 1   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值