IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 对最近刷的一部分题做一个全面的总结 -> 正文阅读

[数据结构与算法]对最近刷的一部分题做一个全面的总结

? ? ? 废话不多说,直接进入正题,对于最近几天刷的算法题进行总结,大部分题需要技巧,但技巧总是忘记,所以记录一下。

  1. 关于数组?
  2. 关于字符串
  3. 关于链表

关于数组:

1.

给定一个整数数组 nums?和一个整数目标值 target,请你在该数组中找出 和为目标值 target??的那?两个?整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]
提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

没有太在意复杂度,基本思路是创建一个长度为2的数组存储答案,两个for循环进行遍历。不考虑复杂度比较简单

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int []result=new int[]{0,1};
         if(nums.length==2){
            return result;
        }
        for(int i=0;i<nums.length;i++){
            for(int m=i+1;m<nums.length;m++){
                if(nums[i]+nums[m]==target){
                    result[0]=i;
                    result[1]=m;
                    return result;
                }
            }
        }
        return result;

    }
}

?

?2.盛水最多的容器

给你?n?个非负整数?a1,a2,...,an,每个数代表坐标中的一个点?(i,?ai)?。在坐标内画?n?条垂直线,垂直线?i?的两个端点分别为?(i,?ai)?和?(i, 0)?。找出其中的两条线,使得它们与?x?轴共同构成的容器可以容纳最多的水。

输入:[1,8,6,2,5,4,8,3,7]
输出:49?
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为?49。
示例 2:

输入:height = [1,1]
输出:1
示例 3:

输入:height = [4,3,2,1,4]
输出:16
示例 4:

输入:height = [1,2,1]
输出:2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

?用双指针,索引对应数据小的一方移动,算出面积,与起初存放的进行比较看是否大于,大于的话更新,小于的话不更新。

public class Solution {
    public int maxArea(int[] height) {
        int l = 0, r = height.length - 1;
        int ans = 0;
        while (l < r) {
            int area = Math.min(height[l], height[r]) * (r - l);
            ans = Math.max(ans, area);
            if (height[l] <= height[r]) {
                ++l;
            }
            else {
                --r;
            }
        }
        return ans;
    }
}

?

3.移动0

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

?通过做题发现,如果需要找某个特定的值,往往可以使用标记,可以用一个元素。比如定义一个fast和slow,当fast一个个遍历,遇到不是0的就放在slow里面,后面直接在后面添0就可以了。

class Solution {
    public void moveZeroes(int[] nums) {
        int slow=0;
        int  len=nums.length;
        for(int  fast=0;fast<len;fast++){
            if(nums[fast]!=0){
                nums[slow]=nums[fast];
                slow++;
            }
            
        }
        for(;slow<len;slow++){
            nums[slow]=0;
        }
       
        
    }
}

4.数组拆分

给定长度为?2n?的整数数组 nums ,你的任务是将这些数分成?n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到?n 的 min(ai, bi) 总和最大。

返回该 最大总和 。

示例 1:

输入:nums = [1,4,3,2]
输出:4
解释:所有可能的分法(忽略元素顺序)为:
1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4
所以最大总和为 4
示例 2:

输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/array-partition-i
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:在本题中需要将数组排序,在排序之后对偶数索引处的值进行计算。

class Solution {
    public int arrayPairSum(int[] nums) {
        Arrays.sort(nums);
        int sum=0;
        for(int i=0;i<nums.length;i=i+2)
        {
            sum=sum+nums[i];

        }
      
       return sum;
    }
}

5.

给定一个已按照 升序排列??的整数数组?numbers ,请你从数组中找出两个数满足相加之和等于目标数?target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

?
示例 1:

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
示例 2:

输入:numbers = [2,3,4], target = 6
输出:[1,3]
示例 3:

输入:numbers = [-1,0], target = -1
输出:[1,2]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int[] res=new int[2];
        int left=0,right=numbers.length-1;
        while(left<right){
            if(numbers[left]+numbers[right]==target){
                res[0]=left+1;
                res[1]=right+1;
                break;
            }else if(numbers[left]+numbers[right]<target){
                left++;
            }else{
                right--;
            }
        }
        return res;
    }
}

?另附一个二分查找元素出现次数的代码

class Solution {
    public int search(int[] nums, int target) {
  int left =0,right = nums.length-1;
        int count = 0;
        while(left<right){
            int mid = (left+right)/2;
            if(nums[mid]>=target)
                right=mid;
            if(nums[mid]<target)
                left = mid+1;
        }
        while(left<nums.length&&nums[left++]==target)
            count++;
        return count;
    }
}


字符串:

1.最后一个单词的长度

给你一个字符串 s,由若干单词组成,单词之间用单个或多个连续的空格字符隔开。返回字符串中最后一个单词的长度。如果不存在最后一个单词,请返回 0?。

单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1:

输入:s = "Hello World"
输出:5
示例 2:

输入:s = " "
输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/length-of-last-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:首先使用trim()函数,消除前后的空格,然后通过spilt分割,得到的是一个数组,直接计算数组最后一个元素的长度?。

class Solution {
    public int lengthOfLastWord(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }

        s = s.trim();
        String[] strs = s.split(" ");
        return strs[strs.length-1].length();
    }
}

2.最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串?""。

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-prefix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:首先取出第一个字符,然后用第一个开始做循环,与后面的字符串进行比较indexOf(String str),来判断是否存在在str字符串,如果不存在就将str的长度减1,通过subString实现

class Solution {
    public String longestCommonPrefix(String[] strs) {
        int i=1;
        String str=strs[0];
        int length=strs.length;
        for(;i<length;i++){
            while(strs[i].indexOf(str)!=0){
                str=str.substring(0,str.length()-1);
            }
          
        }
  return str;
    }
}

?s.chars().sum()可以计算出对应的ascll码之和

class Solution {
    public char findTheDifference(String s, String t) {
        int  a=s.chars().sum();
         int  b=t.chars().sum();
            int  c=b-a;
            return (char)c;
    }
}


给你一个链表的头节点?head?和一个整数?val?,请你删除链表中所有满足?Node.val == val?的节点,并返回?新的头节点?。

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:

输入:head = [], val = 1
输出:[]
示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-linked-list-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。?

思路:插入一个头结点,将其指向head,当找到val时就进行删除,找不到就看下一个元素,但是返回值是dummyhead.next,是为了解决头节点删除的问题。


class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyhead=new ListNode(0);
        dummyhead.next=head;
        ListNode prev=dummyhead;
        while(prev.next!=null){
            if(prev.next.val==val){
                prev.next=prev.next.next;
            }
            else
            {
                prev=prev.next;
            }
        }
            return dummyhead.next;      

    }
}

?

/**
 * 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) {
        while(head!=null &&head.val==val){
            head=head.next;
        }
        ListNode  cur=head;
       while(cur!=null)
       {
           if(cur.next!=null&&cur.next.val==val){
               cur.next=cur.next.next;
           }
           else{
               cur=cur.next;
           }
       }
        return head;

    }
}


给定一个链表,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false 。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

示例 1:

?

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例?2:

?

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:

?

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

?

思路:环形链表,定义一个fast和slow,fast一次走两格,slow一次走一格,如果是环就一定会相遇,记得要判断head是否为空。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null){
            return false;
        }
        ListNode slow=head;
        ListNode fast=head.next;
        while(fast!=null&&fast.next!=null)
        {
          
            if(fast==slow){
                return true;
            }
              fast=fast.next.next;
            slow=slow.next;
            
        }
       
        return false;
    }
}

?


3.反转链表

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

?

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

?

/**
 * 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  prev=null;
        ListNode cur=head;
        while(cur!=null){
                  ListNode  nextnode=cur.next;
                cur.next=prev;
                  prev=cur;
                  cur=nextnode;
        }
        return prev;


    }
}

?代码非常的巧妙。



加油加油加油

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:55:27  更:2021-07-25 11:57:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:33:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码