找出数组中的三个数和为0 的所有三元组(C#实现)

该博客介绍了如何使用C#语言找出数组中所有和为0的三元组。通过排序数组,然后使用双指针法进行遍历,找到满足条件的元素组合。代码实现清晰,易于理解。

示例:输入一个数组{0,1,-1,2,-2,3}找出三个数a,b,c满足a+b+c=0。

输出:0,1,-1

0,2,-2

3,-1,-2

算法思想:

1,先排序

2,在从前往后找,大的左移,小的右移。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> listNum = new List<int>();
            Console.WriteLine("请输入一组数");
            string temp = Console.ReadLine();
            if (!string.IsNullOrEmpty(temp))
            {
                while (!temp.Equals("#"))
                {
                    if (!string.IsNullOrEmpty(temp))
                    {
                        listNum.Add(Convert.ToInt32(temp));
                    }
                    temp = Console.ReadLine();
                }
            }
            
            Console.WriteLine("输出");
            threeSum(listNum);
            Console.ReadKey();


        }
        public static void Sort(List<int> arr)
        {
            for (int i = 1; i < arr.Count; i++)
            {
                int t = arr[i];
                int j = i;
                while ((j > 0) && (arr[j - 1] > t))
                {
                    arr[j] = arr[j - 1];//交换顺序    
                    --j;
                }
                arr[j] = t;
            }
        }

        public static List<List<int>> threeSum(List<int> nums) 
            {

        List<List<int>> my = new List<List<int>>();
        Sort(nums);
        for(int i=0;i<=nums.Count-3;i++)//第一个数小于0之后的不是0就是正数,最后两个不参与循环
            if(nums[i]<=0)
            {
                if(i>=1 && nums[i]==nums[i-1])
                    continue;               
                int j=i+1;
                int k=nums.Count -1;
                while(j<k){
                    if(nums[i]+nums[j]+nums[k]==0)
                    {
                        List<int> one = new List<int>();
                        one.Add(nums[i]);
                        one.Add(nums[j]);
                        one.Add(nums[k]);
                        //在这里不加入到one里直接输出也可以,这样one和my两个数组就没用了。就直接输出在屏幕上不保存


                        my.Add(one);    
                        j++;
                        k--;
                        while(j<k && nums[j]==nums[j-1])
                            j++;
                        while(j<k && nums[k]==nums[k+1])
                            k--;
                    }

                    else {
                        bool flag =true;
                        // 求有序数组中两个数的和为(-1)*nums[i]
                        while(flag){
                            while(j<k && nums[j]+nums[k]>(-1)*nums[i])
                                k--;
                            while(j<k && nums[j]+nums[k]<(-1)*nums[i])
                                j++;
                            if( j>=k || nums[j]+nums[k]==(-1)*nums[i])
                                flag = false;
                        }
                    }
                }   // while(j<k)
            }
            foreach (var all in my)
            {
                for (int m=0;m<all.Count;m++)
                {
                    Console.WriteLine(all[m]+",");
                }
                Console.WriteLine("    ");
            }
            
        return my;
    }
    }
}
想着结构清楚一点,输出的时候直接返回一个需要的list<T>数组,结果输出的时候还要嵌套循环。

呵呵~只为了记录一下~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值