LeetCode 笔记

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

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

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

解:
初步认为是2个指针问题,第一个为i,第二个为i+1。穷举一下就完事了

 public int[] TwoSum(int[] nums, int target)
        {
            int[] ans = new int[] { 0,0};
            int len = nums.Length;
            for (int i = 0; i < len; i++)
            {
                int l = nums[i];
                for (int j = i+1; j < len; j++)
                {
                    int r = nums[j];
                    if(l+r == target)
                    {
                        ans[0] = i;
                        ans[1] = j;
                        return ans;
                    }
                }
            }
            return ans;
        }

但这似乎效率很低 时间复杂度为O(nXn)
看了题解,所要求为找到值为 target-nums[i]的数,那么,用一个字典缓存下即可解决。时间复杂度为nX(hash 表的效率)

  public int[] TwoSum(int[] nums, int target)
        {
            int[] ans = new int[] { 0, 0};
            int len = nums.Length;
            Dictionary<int, int> dic = new Dictionary<int, int>();
            List<int> local = new List<int>();
            for (int i = 0; i < len; i++)
            {
                int v = nums[i];
                var dif = target - v;
                if(dic.ContainsKey(dif))
                {
                    ans[0] = i;
                    ans[1] = dic[dif];
                    return ans;
                }
                else
                {
                    dic[v] = i;
                }
            }
            return ans;
        }
  1. 两数相加
    给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。


这个题目比前一个要复杂,2个指针的都复杂。

对于这种有next节点的单链表,初始化起来会麻烦一些。可以声明一个虚拟头节点,用完之后舍弃它。

 public static  ListNode FormListNode(int[] ary)
        {
            ListNode dump = new ListNode(0, null);
            ListNode f = dump;
            for (int i = 0; i < ary.Length; i++)
            {
                dump.next = new ListNode(ary[i], null);
                dump = dump.next;
            }
            return f.next;
        }

第一次的提交为

 public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
        {
            ListNode dump = new ListNode(0,null);
            ListNode first = dump;
            int pre = 0;
            while(true)
            {
                int l = (l1 != null) ? l1.val : 0;
                int  r = (l2 != null) ? l2.val : 0;

                int v = l + r+pre;
                int cur = v % 10;
                pre = v >= 10 ? 1 : 0;

                ListNode node = new ListNode(cur,null);
                dump.next = node;
                dump = dump.next;

                if(l1!=null)
                {
                    l1 = l1.next;
                }
                
                if(l2!=null)
                {
                    l2 = l2.next;
                }

                if (l1 == null && l2 == null)
                {
                    break;
                }
            }

            if(pre>0)
            {
                ListNode node = new ListNode(pre, null);
                dump.next = node;
                dump = dump.next;
            }

            return first.next;
        }

提交通过了,但是效率应该有些问题。就这样吧

  1. 无重复字符的最长子串
    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度

开始的时候想简单了

  public int LengthOfLongestSubstring(string s)
        {
            int len = s.Length;
            List<char> tmp = new List<char>();
            int max = 0;
            for (int i = 0; i < len; i++)
            {
                var ti = s[i];
                if(!tmp.Contains(ti))
                {
                    tmp.Add(ti);
                }
                else
                {
                    if(tmp.Count>max)
                    {
                        max = tmp.Count;
                    }
                    tmp.Clear();
                    tmp.Add(ti);
                }
            }

            if (tmp.Count > max)
            {
                max = tmp.Count;
            }

            return max;
        }

这样妥妥的错误。测试用例 "dvdf"这样输出的结果居然是2。 思路都不对。
对于循环
a 考虑循环开始
b 考虑循环中
c 考虑循环结束

其中 循环中是错误的。当tmp包含ti时,应该考虑

在这里插入图片描述
修改后为:

 public int LengthOfLongestSubstring(string s)
        {
            int len = s.Length;
            List<char> tmp = new List<char>();
            int max = 0;
            for (int i = 0; i < len; i++)
            {
                var ti = s[i];
                if(!tmp.Contains(ti))
                {
                    tmp.Add(ti);
                }
                else
                {
                    if(tmp.Count>max)
                    {
                        max = tmp.Count;
                    }

                    for (int j = 0; j < tmp.Count; j++)
                    {
                        if(ti == tmp[j])
                        {
                            tmp.RemoveRange(0, j + 1);
                            break;
                        }
                    }
                    tmp.Add(ti);
                }
            }

            if (tmp.Count > max)
            {
                max = tmp.Count;
            }

            return max;
        }

这次正确了。
可以理解为 这是一个滑动窗口,这个窗口一格一格的向前滑动,每滑动一步都保证窗口的值符合要求。

  1. 寻找两个正序数组的中位数
    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

这个题目困难一些。有2个数组,需要2个指针,在取数的时候需要判断是否到了数组末尾。

第一次提交

 public double FindMedianSortedArrays(int[] nums1, int[] nums2)
        {
            int l = 0;
            int r = 0;

            int lp = 0;
            int rp = 0;

            int cur = 0;
            int idx = 0;
            int total = nums1.Length + nums2.Length;
            double ans = 0;
            if(total%2 ==0)
            {
                l = total / 2-1;
                r = l + 1;
            }
            else
            {
                l = (total-1) / 2-1;
                r = l + 2;
            }

            while(true)
            {
                int num = 0;
                if(lp>=nums1.Length)
                {
                    num = nums2[rp++];
                }
                else if(rp>=nums2.Length)
                {
                    num = nums1[lp++];
                }
                else
                {
                    if(nums1[lp]<=nums2[rp])
                    {
                        num = nums1[lp++];
                    }
                    else
                    {
                        num = nums2[rp++];
                    }
                }

                if(idx==l)
                {
                    cur = num;
                }
                if(idx==r)
                {
                    ans = (cur + num) / 2.0d;
                    break;
                }
                idx++;
            }

            return ans;
        }

果然错了,没有考虑到临近条件。两个数组都可能为空的。
处理边界非常麻烦,按照这个思路需要一坨的代码。
各种错误,思路不对重新整理。

这个题目主要按我的理解主要是各种临界条件很难考虑全面。

 public double FindMedianSortedArrays(int[] nums1, int[] nums2)
        {
            int r = 0;
            int lp = 0;
            int rp = 0;

            int pre = 0;
            int idx = 0;
            int l1Len = nums1.Length;
            int l2Len = nums2.Length;
            int total = l1Len + l2Len;
            bool isOdd = total % 2 != 0;
            double dv = 2.0d;

            double ans = 0;
            if(total == 0)
            {
                return 0;
            }
            else if(isOdd)
            {
                r = (total - 1) / 2;
            }
            else
            {
                r = total / 2;
            }

            while(true)
            {
                int num = 0;
                if (lp >= l1Len)
                {
                    if (rp >= l2Len)
                    {
                        num = 0;
                    }
                    else
                    {
                        num = nums2[rp++];
                    }
                }
                else if(rp>= l2Len)
                {
                    if(lp>= l1Len)
                    {
                        num = 0;
                    }
                    else
                    {
                        num = nums1[lp++];
                    }
                }
                else
                {
                    if (nums1[lp] <= nums2[rp])
                    {
                        num = nums1[lp++];
                    }
                    else
                    {
                        num = nums2[rp++];
                    }
                }
                if(idx>=r)
                {
                    if(isOdd)
                    {
                        ans = num;
                    }
                    else
                    {
                        ans = (num + pre) / dv;
                    }
                    
                    break;
                }
                pre = num;
                idx++;
            }

            return ans;
        }

这次提交通过了思路:
取左面数组的数还是取右面数组的数需要严格按照条件判定。
取值完了之后需要按照奇数还是偶数求值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值